Reputation: 1735
I have a landing page in React with below function for changing image in carousel.
After I navigate away, it gives error 'Can't perform a React state update on an unmounted component.'
Below function change carousel image in every 2 second.
// state to find idex
const [imageIndex, setImageIndex] = React.useState(0);
//array of images to display
const images = [
image1,image3,image2,
];
//function that changes image index in every 2 second
const nextImage = () => {
setImageIndex((prev) => (prev + 1) % images.length);
setTimeout(nextImage, 2000);
};
// function to initiate above function, the memory leak happens here
React.useEffect(nextImage, []);
I have gone through some StackOverflow questions and changed my timing function as below but the error still exists,
// useEffect triggers this functions
const nextImage = () => {
let unmounted = false;
if (!unmounted) {
setImageIndex((prev) => (prev + 1) % images.length);
setTimeout(nextImage, 2000);
}
return () => {
unmounted = true;
};
};
Question I referred https://stackoverflow.com/a/58038029/10515390 have answer but I did not get the clear idea.
Upvotes: 0
Views: 239
Reputation: 6067
Here i've created a simple snippet for you. Hope you'll understand this. And since you are using setTimeout
make sure you've also used clearTimeout
. And re run the effect when the image index changes.
const {useState, useEffect} = React;
function Test() {
const [imageIndex, setImageIndex] = React.useState(0);
const images = [ 'image1','image2','image3'];
useEffect(() => {
let timeoutId = setTimeout(() => {
setImageIndex((imageIndex+1) %images.length);
}, 2000);
return () => {
clearTimeout(timeoutId)
}
}, [imageIndex])
return <h2>{images[imageIndex]}</h2>
}
ReactDOM.render(
<Test/>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 2