如何在useEffect清理函数中取消异步任务?解决React内存泄漏警告
解决React组件卸载后状态更新的内存泄漏警告
问题原因
你遇到的警告是因为Products组件在异步请求完成前就已卸载,但请求结束后依然调用setProducts尝试更新已卸载组件的状态,这会引发内存泄漏。主页无法加载可能和异步请求的异常处理不完整、组件状态更新逻辑冲突有关。
解决方案
针对你的Products.js代码,提供两种常用修复方式:
方法1:用AbortController取消axios请求
利用浏览器AbortController接口,在组件卸载时直接取消未完成的请求,从根源避免后续状态更新:
const [products, setProducts] = useState([]); useEffect(() => { const controller = new AbortController(); const signal = controller.signal; const getProducts = async () => { try { const res = await axios.get( category ? `http://localhost:5000/e-mart/products?category=${category}` : `http://localhost:5000/e-mart/products`, { signal } // 将取消信号传入请求配置 ); setProducts(res.data); } catch (err) { // 忽略请求被取消的报错 if (err.name !== 'CanceledError') { console.log(err.message); } } }; getProducts(); // 组件卸载时触发请求取消 return () => controller.abort(); }, [category]);
方法2:用挂载状态标记控制更新
通过布尔变量跟踪组件挂载状态,仅在组件处于挂载状态时执行状态更新:
const [products, setProducts] = useState([]); useEffect(() => { let isMounted = true; const getProducts = async () => { try { const res = await axios.get( category ? `http://localhost:5000/e-mart/products?category=${category}` : `http://localhost:5000/e-mart/products` ); // 仅组件挂载时更新状态 if (isMounted) { setProducts(res.data); } } catch (err) { console.log(err.message); } }; getProducts(); // 组件卸载时标记为未挂载 return () => { isMounted = false; }; }, [category]);
额外排查点
如果主页仍无法加载,建议:
- 查看浏览器控制台的其他错误信息,确认是否存在请求失败情况
- 验证后端接口
http://localhost:5000/e-mart/products能否正常返回数据 - 检查
category状态的变化是否符合预期,避免因值异常导致请求错误
内容的提问来源于stack exchange,提问作者Emdadudl Haque Apu
相关产品推荐
相关产品推荐

