I have useEffect
callback where I'm fetching some data from several API. To do that I'm using Promise
and my code looks like that:
useEffect(() => {
const fetchAllData = async () => {
const resourceOne = new Promise((resolve) => {
// fetching data from resource one and changing some states
})
const resourceTwo = new Promise((resolve) => {
// fetching data from resource two and changing some states
})
const resourceThree = new Promise((resolve) => {
// fetching data from resource three and changing some states
})
await Promise.all([resourceOne, resourceTwo, resourceThree])
.then(() => {
// changing some states
})
}
return fetchAllData()
},[])
How I understand in this situation useEffect
unmount before fetching all data and then gives me an warning
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.
So how to write correctly cleanup code to avoid this warning?
You can use a boolean and toggle it in the cleanup function (the function that is returned in the callback passed to useEffect
)
useEffect(() => {
let shouldUpdate = true;
const fetchAllData = () => {
const resourceOne = new Promise((resolve) => {
// fetching data from resource one and changing some states
})
const resourceTwo = new Promise((resolve) => {
// fetching data from resource two and changing some states
})
const resourceThree = new Promise((resolve) => {
// fetching data from resource three and changing some states
})
Promise.all([resourceOne, resourceTwo, resourceThree])
.then(() => {
if(shouldUpdate) {
// update state
}
})
}
fetchAllData()
return () => {
shouldUpdate = false;
}
},[])
If the component is unmounted the cleanup function will be called and shouldUpdate
will change to false. When the promises resolve, the state will not update as shouldUpdate
is no longer true.