使用useEffect()获取数据时频繁发起GET请求的问题求助
解决React useEffect无限发起API请求的问题
问题原因
你当前的代码把products作为useEffect的依赖项,每次调用setProducts更新状态后,products的引用会发生变化,进而重新触发useEffect发起请求,请求完成后又会更新状态,形成无限循环,导致每秒多次发起GET请求。
解决方案
方案1:仅在组件挂载时请求一次
如果你的需求是页面加载时获取一次数据,直接将依赖数组设为空[],这样useEffect只会在组件首次渲染时执行一次:
const [products, setProducts] = useState({ baskets: [] }); useEffect(() => { fetch("/api") .then((response) => response.json()) .then((data) => { setProducts(data); }); }, []); // 空依赖数组,仅组件挂载时执行
方案2:监听API更新的触发条件
如果需要仅在特定场景下(比如外部操作触发API数据更新)发起请求,可以新增一个专门的触发标识作为依赖:
const [products, setProducts] = useState({ baskets: [] }); // 用数值变化作为API更新的触发标识 const [apiUpdateTrigger, setApiUpdateTrigger] = useState(0); // 当需要更新API数据时,调用这个函数触发请求 const triggerApiRefresh = () => { setApiUpdateTrigger(prev => prev + 1); }; useEffect(() => { fetch("/api") .then((response) => response.json()) .then((data) => { setProducts(data); }); }, [apiUpdateTrigger]); // 仅当触发标识变化时发起请求
额外优化:避免内存泄漏
为了防止组件卸载时仍在处理请求导致内存泄漏,可以添加请求取消逻辑:
const [products, setProducts] = useState({ baskets: [] }); useEffect(() => { const controller = new AbortController(); const signal = controller.signal; fetch("/api", { signal }) .then((response) => response.json()) .then((data) => { setProducts(data); }) .catch((error) => { // 忽略取消请求的报错 if (error.name !== 'AbortError') { console.error('API请求失败:', error); } }); // 组件卸载时取消未完成的请求 return () => controller.abort(); }, []);
内容的提问来源于stack exchange,提问作者Mustafa Mengütay
相关产品推荐
相关产品推荐

