React中如何使用useEffect避免不必要的API重复调用?
React useEffect空依赖数组下API重复调用问题
问题描述
React初学者在实现列表渲染功能时遇到异常:为useEffect传入空依赖数组,预期相关请求逻辑仅在组件挂载时执行一次,但实际运行中API始终处于被重复调用的状态,无法定位问题产生的原因。
问题复现代码
import React from "react"; import axios from "axios"; import "./styles.css"; const App = () => { const BASE_URL = "https://pokeapi.co/api/v2"; const [pokemons, setPokemons] = React.useState([]); const getAllPokemons = async () => { const { data } = await axios.get(`${BASE_URL}/pokemon`); data.results.map((pokemon) => getPokeType(pokemon)); }; const getPokeType = async (pokemon) => { const { data } = await axios.get(pokemon.url); setPokemons((prev) => [...prev, data]); }; React.useEffect(() => { getAllPokemons(); }, []); console.log(pokemons); return ( <div className="App"> <h1>Hello CodeSandbox</h1> {pokemons.map((pokemon) => ( <p key={pokemon.id} style={{ color: "blue" }}> {pokemon.name} </p> ))} </div> ); }; export default App;
问题根因
重复调用由两个因素共同导致:
- React 18 严格模式默认行为:开发环境下严格模式会自动执行「组件挂载→卸载→重新挂载」流程,用于提前检测未写清理逻辑的副作用,即使
useEffect传入空依赖数组,开发环境下副作用逻辑也会执行2次,这是框架的设计行为,不是依赖配置错误。 - 频繁状态更新触发多次重渲染:现有代码中每获取到1个宝可梦的详情数据就调用一次
setPokemons,接口默认返回20条宝可梦数据,就会触发20次组件重渲染,控制台多次打印日志会进一步放大“接口无限重复调用”的观感。
修复方案
- 为
useEffect添加清理逻辑,组件卸载时取消未完成的请求,避免严格模式下二次挂载触发重复请求、以及组件卸载后状态更新报错的问题。 - 优化状态更新逻辑:等待所有宝可梦详情请求全部返回后,一次性更新
pokemons状态,减少不必要的重渲染。
修复后核心代码示例:
React.useEffect(() => { const controller = new AbortController(); const signal = controller.signal; const getAllPokemons = async () => { try { const { data } = await axios.get(`${BASE_URL}/pokemon`, { signal }); // 等待所有详情请求并行完成 const pokeDetailList = await Promise.all( data.results.map(async (pokemon) => { const res = await axios.get(pokemon.url, { signal }); return res.data; }) ); setPokemons(pokeDetailList); } catch (err) { // 主动取消的请求不需要抛出错误 if (axios.isCancel(err)) return; console.error(err); } }; getAllPokemons(); // 组件卸载时终止所有未完成的请求 return () => controller.abort(); }, []);
补充说明:如果不需要严格模式的开发检测能力,可以直接移除入口文件中包裹根组件的
<React.StrictMode>标签,但更推荐按照上述方案补全副作用清理逻辑,从根源上避免线上环境出现内存泄漏、已卸载组件状态更新报错等问题。
内容的提问来源于stack exchange,提问作者Katyellen
相关产品推荐
相关产品推荐

