You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:50:38