React异步函数调用useState时useEffect正确使用及无限循环问题咨询
问题原因
- 无限循环的核心原因:你直接在组件顶层调用了
fetchInfo函数。组件每次渲染都会执行顶层代码,fetchInfo执行完会调用setRetrievedData更新状态,状态更新触发组件重新渲染,重新渲染又会再次执行fetchInfo,形成死循环。 - 你贴出的代码中
useEffect的依赖项是retrievedData,且回调里的setRetrievedData没有传参属于无效代码,即便你把依赖改成空数组,只要顶层的fetchInfo调用没移除,依然会触发循环。 - Promise.all执行两次是React 18严格模式的开发环境特性,会模拟组件挂载、卸载、重新挂载的流程,用来排查副作用泄露问题,生产环境不会复现,属于正常现象。
- 异步逻辑写法冗余:
promiseData.map((resp) => resp.json())返回的是Promise数组,直接用await不会等待所有Promise执行完成,后续的循环await可以直接合并成一次Promise.all调用,简化代码。
修复后代码
const [retrievedData, setRetrievedData] = useState([]); async function fetchInfo() { // 修复原代码多余的右括号语法错误 const promiseData = await Promise.all(<我的请求链接数组>); // 直接等待所有json解析完成,不需要后续循环逐个await const actualData = await Promise.all(promiseData.map(resp => resp.json())); setRetrievedData(actualData); } useEffect(() => { // 将fetchInfo放到useEffect里执行,依赖为空数组只会在挂载时执行一次 fetchInfo(); }, []);
内容的提问来源于stack exchange,提问作者Thanos Dodd
相关产品推荐
相关产品推荐

