【问题标题】:How to stop useEffect memory leak in react hook如何在反应钩子中停止useEffect内存泄漏
【发布时间】:2021-05-25 21:58:22
【问题描述】:

我正在使用useEffect 钩子从服务器获取数据,这些数据被传递到一个列表,当我注册时,我收到如下警告

无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

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

useEffect(() => {
  getUserData();
}, []);

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

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

【问题讨论】:

  • history.push('/signin); 中有语法错误。您需要关闭报价
  • 我已经更新了
  • 就像错误消息说的那样,你需要通过返回一个清理函数来清理你的useEffect钩子启动的所有异步任务。在调用 setState 之前,使用它来中止请求或确保组件仍然挂载。
  • 看起来您的 API 请求在您通过 history.push('/signin') 导航离开此组件之后返回。在您的 useEffect 中返回一个函数来处理它。

标签: reactjs react-hooks


【解决方案1】:

当您的组件被销毁时会发生这种情况,其中一些要执行的代码是在销毁之后完成的。在您的情况下,这是 API 调用的回调 setUserData(res.data);

由于您使用 Axios 进行 http 调用,我建议使用取消令牌来取消对组件销毁的 API 调用。

从 axios 生成取消令牌,将其传递给方法 getUserData 并提供给 axios 调用。 对于将在组件销毁时执行的 useEffect 返回方法(并取消该代码,从而取消该回调并设置状态):

const getUserData = (cancelToken) => {
  axios.get(`${API_URL}`, {cancelToken: cancelToken.token}).then((res) => {
    if (res.data) {
      setUserData(res.data);
    }
  });
};

useEffect(() => {
  const cancelToken = axios.CancelToken.source();
  getUserData(cancelToken);

  return () => {
    cancelToken.cancel();
  }
}, []);

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

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

【讨论】:

    猜你喜欢
    • 2020-01-22
    • 2021-05-27
    • 2021-10-14
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    相关资源
    最近更新 更多