I have a React component that fetches a array of movies and then sets those movies on a state:
// randomBackground.tsx
const [movieData, setMovieData] = useState<IMovie []>([]);
useEffect(() => {
const abortCtrl = new AbortController();
const opts = {signal: abortCtrl.signal};
const fetchData = () => {
try {
fetch(baseurl apikey rest, opts)
.then((response) => response.json())
.then((data) => {
setMovieData(data.results);
});
} catch (e) {
console.log(e);
}
};
fetchData();
return () => abortCtrl.abort();
}, []);
I show this component when a user has not logged in:
// app.tsx
return (
{currentUser.isLoggedIn ? <DashboardComponent /> : <RandomBackground />}
)
When the user logs in the DashboardComponent
takes over. But I get the error:
react-dom.development.js?61bb:67 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. at RandomBackground
So the randomBackground
component tries to set a value on the setMovieData
state which doesn't exist anymore.
If I google the error I get a lot post regarding the AbortController
or setting an boolean value, but none of them work. Am I implementing the solution incorrectly?
CodePudding user response:
Use a boolean flag to check if the component has been unmounted and update the state only if it has not (been unmounted).
const [movieData, setMovieData] = useState<IMovie[]>([]);
useEffect(() => {
let isRequestCancelled = false;
const fetchData = () => {
try {
fetch(baseurl apikey rest, opts)
.then((response) => response.json())
.then((data) => {
if (!isRequestCancelled) {
setMovieData(data.results);
}
});
}
catch (e) {
console.log(e);
}
};
fetchData();
return () => {
isRequestCancelled = true;
};
}, []);