如何在反应钩子中阻止useEffect内存泄漏

时间:2021-05-25 21:58:22

标签: reactjs react-hooks

我正在使用 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>
);

1 个答案:

答案 0 :(得分:2)

当您的组件被销毁时,会发生这种情况,其中一些代码在销毁后完成。在您的情况下,这是 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>
);