javascript - 如何摆脱 React Web 应用程序中的内存泄漏
问题描述
我的 ReactJS Web 应用程序中有这段代码:
useEffect(() => {
const fetchInfo = async () => {
const res = await fetch(`${api}&page=${page}`);
setLoading(true);
try {
const x = await res.json();
if (page === 1) {
setItems(x);
setAutoplay(true);
} else {
setItems({
hasMore: x.hasMore,
vacancies: [...items.vacancies, ...x.vacancies],
});
}
} catch (err){
console.log(err);
}
setLoading(false);
};
fetchInfo();
}, [page]);
当此组件在运行异步函数时卸载时,它会在控制台中引发错误。
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
如何在清理中取消异步任务。
解决方案
我在这里假设这setLoading
是在您的组件卸载后设置状态的函数,因此会引发此警告。如果是,那么您需要的是清理功能。
传递给的函数useEffect
可以返回一个函数,该函数将在组件卸载之前调用(您可以将其视为 old 的等价物componentWillUnmount
) - 更多细节在这里:
https://reactjs.org/docs/hooks-effect.html#example-using-hooks
现在您可能想要的是某种标志来检查您调用 是否安全,setLoading
即将该标志设置为true
默认值,然后false
在返回函数中将其设置为。这是一篇应该有所帮助的好文章:
https://juliangaramendy.dev/use-promise-subscription/
现在我还没有对此进行测试,但基本上你的代码看起来像这样:
useEffect(() => {
const fetchInfo = async () => {
let isSubscribed = true;
const res = await fetch(`${api}&page=${page}`);
if (isSubscribed) setLoading(true);
try {
const x = await res.json();
if (page === 1) {
setItems(x);
setAutoplay(true);
} else {
setItems({
hasMore: x.hasMore,
vacancies: [...items.vacancies, ...x.vacancies]
});
}
} catch (err) {
console.log(err);
}
if (isSubscribed) setLoading(false);
return () => (isSubscribed = false);
};
fetchInfo();
}, [page]);
推荐阅读
- java - Firebase 会话管理:设置全局用户的问题
- android - 为什么我在真实设备中的应用程序与 android studio 中的布局预览之间存在差异
- amazon-web-services - 如何从 AWS SAM 本地 docker 实例连接到主机 MySQL?
- python - 在一列中拆分多个字段
- javascript - 错误找不到“object”类型的不同支持对象“[object Object]”。NgFor 仅支持绑定到 Iterables,例如 Arrays
- php - 如何在 Widget 类中创建类
- git - git rebase 提交
- postgresql - 左连接两个表 - 不包括第二个表有超过 1 行的第一个表值的连接;拒绝
- java - OpenCV检测钻孔
- batch-file - 如何仅执行文件夹中名称以两位数开头的所有 SQL 文件,而忽略所有其他 SQL 文件?