reactjs - 即使我正在清理我的 useEffect,如何避免我的反应应用程序中的内存泄漏警告?
解决方案
当您尝试在已卸载的组件上设置状态时,会发生这种情况。这在您发出异步请求的异步操作中很常见,然后您尝试在它解析后设置状态。
过程是这样的:
- 组件安装
- useEffect 运行并触发异步请求
- async 函数在设置状态函数周围创建一个闭包
- 组件卸载(由于任何原因导致 UI 发生变化)
- 请求解决
- 调用了闭包设置状态函数 - 但包含状态的组件已经卸载!错误发生在这里。
要解决此问题,您需要在调用状态更新函数之前检查组件是否仍然挂载。
useIsMounted
您可以使用诸如钩子之类的东西来检查组件是否已安装。网上有很多这个钩子的例子。
HMR 评论了一个好useIsMounted
钩子的链接,我将在此处发布:
import { useRef, useEffect } from 'react';
const useIsMounted = () => {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => isMounted.current = false;
}, []);
return isMounted;
};
export default useIsMounted;
要使用该钩子,您可以在组件中调用它:
const isMounted = useIsMounted()
在您的异步函数中,在设置状态之前检查组件是否已安装:
if(isMounted.current) {
// it's okay to set state here
}
确保将isMounted
变量添加为您的依赖项,useEffect
以便您拥有最新的值!
推荐阅读
- python - pandas max 函数导致 DataFrame 无法运行
- python - 为什么在读取包含大量行的文件时使用多线程这么慢?
- python-3.x - ModuleNotFoundError:烧瓶程序中没有名为“pandas”的模块
- java - 如何在 JAVA 中通知类中的所有线程?
- javascript - document.body.appendChild(form) 复制页面底部的表单
- scala - 将字符串列转换为特定格式的日期
- c# - 如何将 SocketIO 与 C# 客户端连接
- oracle - 如何导出/导入完整的 OracleDB 数据转储?
- java - 从链表中搜索并删除一个节点
- azure - 使用 Azure 数据工厂进行参数化