I am using Effect hook to fetch the datas from server and these data are passed to the react table there i have used the same api call to load the next set of datas from server. When the application gets loaded i am getting an warning like below
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.
Effect Hook:
useEffect(() => {
setPageLoading(true);
props
.dispatch(fetchCourses())
.then(() => {
setPageLoading(false);
})
.catch((error: string) => {
toast.error(error);
setPageLoading(false);
});
}, []);
React Table Page:
<ReactTable
className="-striped -highlight"
columns={columns}
data={coursesData}
defaultPage={currentPage}
defaultPageSize={courses.perPage}
loading={isLoading}
manual={true}
onFetchData={setFilter}
/>
Set Filter function:
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);
});
};
Does anyone know how to clean up the hook in react
With useEffect you can return a function that will be run on cleanup. So in your case, you'll want something like this:
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 };
}, []);
EDIT: if you need to have a call that's kicked off outside of useEffect, then it will still need to check an unmounted variable to tell whether it should skip the call to setState. That unmounted variable will be set by a useEffect, but now you need to go through some hurdles to make the variable accessible outside of the effect.
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 */ />
);
}