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

React Hook中如何解决useEffect触发的内存泄漏警告问题

React useEffect异步请求内存泄漏警告修复方案

问题原因

你遇到的警告触发逻辑非常清晰:点击登出后history.push('/signin')会卸载当前页面组件,但你在useEffect中触发的axios异步请求还在pending状态,等请求成功返回执行setUserData更新组件状态时,目标组件已经被销毁,React就会抛出该警告,未被处理的异步任务也会造成内存泄漏风险。

修复方案

方案1:使用AbortController取消未完成请求(推荐)

Axios从v0.22.0开始支持用AbortController取消请求,直接从根源终止未完成的异步任务,避免后续无效的状态更新,同时节省网络资源。
修改后的代码如下:

useEffect(() => {
  // 实例化中断控制器
  const controller = new AbortController();

  const getUserData = () => {
    axios.get(`${API_URL}`, {
      // 绑定中断信号到当前请求
      signal: controller.signal
    }).then((res) => {
      if (res.data) {
        setUserData(res.data);
      }
    }).catch(err => {
      // 忽略请求主动取消的错误
      if (axios.isCancel(err)) return;
      // 其他业务错误正常处理
      console.error('用户数据请求失败', err);
    })
  };

  getUserData();

  // 组件卸载时执行的清理函数
  return () => {
    controller.abort();
  };
}, []);

const logout = () => {
  signout(() => {
    history.push('/signin');
  });
};

return (
  <div>
    <button onClick={() => logout()}>Sign out </button>
  </div>
);

方案2:挂载状态标记(兼容旧版本Axios)

如果你使用的Axios版本较低不支持AbortController,可以用ref标记组件挂载状态,请求返回后只有组件还处于挂载状态才更新状态。该方案不会终止请求,仅跳过无效的状态更新操作。
修改后的代码如下:

useEffect(() => {
  // 标记组件是否处于挂载状态
  let isMounted = true;

  const getUserData = () => {
    axios.get(`${API_URL}`).then((res) => {
      if (isMounted && res.data) {
        setUserData(res.data);
      }
    });
  };

  getUserData();

  return () => {
    // 组件卸载时修改标记
    isMounted = false;
  };
}, []);

内容的提问来源于stack exchange,提问作者Gabriel Udo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 20:15:03