我正在使用 Effect hook 从服务器获取数据,这些数据被传递到 react 表,我在那里使用相同的 api 调用从服务器加载下一组数据。 当应用程序加载时,我收到如下警告
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.
效果 Hook :
useEffect(() => {
setPageLoading(true);
props
.dispatch(fetchCourses())
.then(() => {
setPageLoading(false);
})
.catch((error: string) => {
toast.error(error);
setPageLoading(false);
});
}, []);
react 表页面:
<ReactTable
className="-striped -highlight"
columns={columns}
data={coursesData}
defaultPage={currentPage}
defaultPageSize={courses.perPage}
loading={isLoading}
manual={true}
onFetchData={setFilter}
/>
设置过滤功能:
const setFilter = (pagination: any) => {
props.dispatch(updateCoursePageSize(pagination.pageSize));
props.dispatch(updateCourseCurrentPage(pagination.page + 1));
setCurrentPage(pagination.page);
setPerPage(pagination.pageSize);
setLoading(true);
props.dispatch(fetchCourses()).then(() => {
setLoading(false);
});
};
有谁知道如何清理react中的hook
最佳答案
更新(2022 年 6 月):
React 18 已删除此警告消息,并且可能不再需要消除它的解决方法。他们删除它的部分原因是它总是有点误导。它说你有内存泄漏,但很多时候你并没有。
问题中的代码(实际上是导致此警告的大多数代码)在组件卸载后运行有限的时间,然后设置状态,然后完成运行。由于运行完毕,javascript 可以释放其闭包中的变量,因此通常不会发生泄漏。
如果您正在设置无限期持续的持久订阅,则会出现内存泄漏。例如,也许您设置了一个 websocket 并监听消息,但您从未拆除该 websocket。这些情况确实需要修复(通过向 useEffect
提供清理函数),但它们并不常见。
原始答案(2019 年 9 月):
使用 useEffect,您可以返回一个将在清理时运行的函数。因此,就您而言,您需要这样的东西:
useEffect(() => {
let unmounted = false;
setPageLoading(true);
props
.dispatch(fetchCourses())
.then(() => {
if (!unmounted) {
setPageLoading(false);
}
})
.catch((error: string) => {
if (!unmounted) {
toast.error(error);
setPageLoading(false);
}
});
return () => { unmounted = true };
}, []);
编辑:如果您需要在 useEffect 之外启动调用,那么它仍然需要检查未安装的变量以判断是否应该跳过对 setState 的调用。未安装的变量将由 useEffect 设置,但现在您需要克服一些障碍才能在效果之外访问该变量。
const Example = (props) => {
const unmounted = useRef(false);
useEffect(() => {
return () => { unmounted.current = true }
}, []);
const setFilter = () => {
// ...
props.dispatch(fetchCourses()).then(() => {
if (!unmounted.current) {
setLoading(false);
}
})
}
// ...
return (
<ReactTable onFetchData={setFilter} /* other props omitted */ />
);
}
关于reactjs - 如何阻止 useEffect hook React 中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58038008/