React调用API时发生过多重渲染问题,该如何排查与解决?
问题原因
你的代码出现无限重渲染的核心原因是useEffect没有传入第二个依赖数组参数:
- React中如果
useEffect不指定依赖数组,会在每一次组件渲染完成后都执行
你当前的执行逻辑形成了无限循环:组件渲染→执行useEffect发请求→拿到数据调用setData更新状态→状态变更触发组件重渲染→重渲染完成又执行useEffect,所以会反复打印console.log("test")。
解决方法
根据你的使用场景选择对应方案:
- 如果接口只需要在组件第一次挂载完成后请求1次,给
useEffect添加空依赖数组即可:
useEffect(() => { fetch("https://61924463aeab5c0017105ebe.mockapi.io/test") .then((res) => res.json()) .then( (result) => { if (result) { console.log("test"); setData(result); } }, (error) => { console.log(error); } ); }, []); // 新增空数组作为依赖
- 如果接口请求需要依赖特定变量(比如分页参数、搜索关键词),就把这些变量放到依赖数组中,只有变量发生变化时才会重新执行请求:
const [page, setPage] = useState(1); useEffect(() => { // 带参数的请求逻辑 }, [page]); // 只有page变化时才重新发请求
额外优化建议
- 可以添加请求中断逻辑,避免组件卸载后请求还在执行导致的内存泄漏:
useEffect(() => { const controller = new AbortController(); fetch("https://61924463aeab5c0017105ebe.mockapi.io/test", { signal: controller.signal }) .then((res) => res.json()) .then( (result) => { if (result) { console.log("test"); setData(result); } }, (error) => { // 中断请求会抛出AbortError,可自行判断是否忽略该报错 console.log(error); } ); return () => controller.abort(); // 组件卸载时中断未完成的请求 }, []);
- 列表渲染的
key最好使用唯一值,你当前用row.name可能存在重复风险,替换为key={row.id}更稳妥。
内容的提问来源于stack exchange,提问作者nipoo
相关产品推荐
相关产品推荐

