如何通过Rest Countries API按名称搜索并解决React DOM更新异常问题
问题修复:Rest Countries API搜索后DOM不更新且避免过度渲染
核心问题分析
useEffect的依赖数组为空,仅在组件首次挂载时执行一次请求,后续searchInput变更不会触发新的API调用,导致DOM无法更新。handleSubmit中调用fetchCountry()时未传入参数,请求会使用undefined作为搜索关键词,导致请求无效。countryData初始值设为数组,但接口返回的是单个国家对象,类型不匹配可能引发后续渲染问题。
修复后的完整代码
状态与请求函数
const countryUrl = `https://restcountries.com/v2/name`; // 修正countryData的初始类型,匹配接口返回的单个对象格式 const [searchInput, setSearchInput] = useState<string>("Nigeria"); const [countryData, setCountryData] = useState<object | null>(null); const fetchCountry = (countryName: string) => { axios .get(`${countryUrl}/${countryName}?fullText=true`) .then((res) => setCountryData(res.data[0])) .catch((err) => console.log(err)); };
副作用与提交处理
// 加入searchInput到依赖数组,仅当搜索词变化时触发请求 // 新增防抖逻辑,避免输入过程中频繁发起API请求 useEffect(() => { const delayTimer = setTimeout(() => { fetchCountry(searchInput); }, 300); // 清理定时器,防止组件卸载或搜索词变更时触发无效请求 return () => clearTimeout(delayTimer); }, [searchInput]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); fetchWeather(searchInput); // 手动调用时传入正确的搜索参数 fetchCountry(searchInput); };
表单组件
<form onSubmit={handleSubmit}> <input onChange={(e) => setSearchInput(e.target.value)} placeholder="Enter The Country" type="text" value={searchInput} // 绑定value,实现受控组件 /> <button type="submit"><CiSearch /></button> </form>
关键优化说明
- 依赖数组配置:将
searchInput加入useEffect的依赖数组,确保搜索词变更时自动触发请求,同时避免无意义的重复渲染。 - 防抖处理:通过300ms延迟执行请求,减少输入过程中的API调用次数,优化性能的同时避免过度渲染。
- 受控输入框:给input绑定
value={searchInput},保证输入框状态与React状态完全同步,消除潜在的状态不一致问题。 - 参数修正:在
handleSubmit中调用fetchCountry时传入searchInput,确保请求使用正确的搜索关键词。 - 类型匹配:调整
countryData的初始类型为object | null,与接口返回的单个国家对象格式一致,避免类型错误。
内容的提问来源于stack exchange,提问作者Mayowa
相关产品推荐
相关产品推荐

