const [index, setIndex] = useState(0);
useEffect(()=>{
if (index === 3){
setIndex(0)
console.log(index)
}else{
setTimeout(() => setIndex((index) => index 1), 2000);
console.log(index)
}
}, [index]);
So my question is why is this code above skips 1 the first time? The console.log() gives back the following 0 0 2 3 0 1 2 3 0 now here I understand the 0 0 cause I logging it out then the 2 for some reason I don't get it and again 3 0 1 2 is understandable
I want to change the name in the DOM according the index of it in an array
CodePudding user response:
In developement mode the useEffect
will run twice on mount because of StrictMode.
So the setTimeout
will run twice and since you're not providing a cleanup function it will live on and keep setting the state. Which results in setting the state twice and so going from 0
to 2
.
In production StrictMode is disabled and thus will not fire the useEffect
twice.
Instead you could do something like this
useEffect(() => {
let timeoutId;
if (index === 3) {
setIndex(0);
console.log(index);
} else {
timeoutId = setTimeout(() => setIndex((index) => index 1), 2000);
console.log(index);
}
return () => clearTimeout(timeoutId);
}, [index]);
However if you're trying to make some sort of counter/interval I recommend using setInterval.
useEffect(() => {
// set id to use in the cleanup
const timerId = setInterval(
() =>
// use inline check so we have access to the actual index
setIndex((prevIndex) => {
if (prevIndex === 3) return 0;
return prevIndex 1;
}),
2000
);
return () => clearInterval(timerId);
}, []);