React中调用接口给useState定义的状态赋值时触发无限循环问题
问题原因及修复方案
- 无限循环根因:你直接将
fetch请求写在了组件函数体顶层,React组件每次渲染都会执行函数体内所有代码,fetch请求成功后调用setCountries会触发组件重新渲染,新的渲染又会再次执行fetch、更新state,由此进入无限循环。 - state更新逻辑存在两处错误:
- 语法错误:
setCountries(...countries, {xxx})的传参方式错误,setCountries接收的是一个完整的新数组,正确的追加写法应为setCountries([...countries, {xxx}]) - 逻辑错误:在循环中反复调用
setCountries不仅性能差,还会因为闭包问题拿到旧的countries值,导致最终state数据不符合预期
- 语法错误:
正确实现代码
import { useState, useEffect } from 'react'; function AllCountries() { const [countries, setCountries] = useState([]); // 用useEffect包裹请求,空依赖项保证仅组件首次挂载时执行1次 useEffect(() => { fetch(`https://restcountries.eu/rest/v2/all`) .then((r) => r.json()) .then((data) => { if (data) { // 先批量处理所有数据生成目标数组,再一次性更新state const formattedCountries = data.map(ob => ({ flag: ob.flag, name: ob.name, population: ob.population, region: ob.region, capital: ob.capital })); setCountries(formattedCountries); } else { alert("Can´t Load Data"); } }) .catch(err => { alert("数据加载失败:" + err.message); }); }, []); return ( <div>PRUEBA</div> ); }
额外优化建议
- 可以新增加载状态、错误状态的state,用于页面展示加载中、加载失败的提示
- 请求得到的data可以先做结构校验,避免接口返回格式变化导致页面报错
内容的提问来源于stack exchange,提问作者miouri
相关产品推荐
相关产品推荐

