I'm trying to make a simple setInterval function for a typing game but it keeps glitching out depending on my syntax or not updating at all as it is now.
How do I get this to update every second and call the functions in the if statement?
const [counter, setCounter] = useState(10);
useEffect(() => {
let timer = setInterval(() => {
setCounter(counter - 1);
if (counter === 0) {
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
setCounter(10);
}
}, 1000);
}, []);
*********Edit***************
This is what I have now that is working. The first answer fixed the async issue of the counter not decrementing but I had to move the if statement outside of the useEffect to correct what I believe was caused by this same problem.
useEffect(() => {
let timer = setInterval(() => {
setCounter( counter => counter - 1);
}, 1000);
}, []);
if (counter == 0) {
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
setCounter(10);
}
Use callback function in setCounter
function. As you are calling the state update in an async function. it's good practice to update the state based on the previous state.
const [counter, setCounter] = useState(10);
useEffect(() => {
let timer = setInterval(() => {
setCounter(counter => {
const updatedCounter = counter - 1;
if (updatedCounter === 0) {
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
return 10;
}
return updatedCounter;
}); // use callback function to set the state
}, 1000);
return () => clearInterval(timer); // cleanup the timer
}, []);
The previous answers aren't considering the counter values aren't immediately updating. They are also prone memory leaks since setInterval isn't cleared.
const [counter, setCounter] = useState(10);
useEffect(() => {
let timer = setInterval(() => {
setCounter( counter => {
const nC = counter - 1;
if (nC === 0) {
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
return 10;
}
return nC;
});
}, 1000);
return () => clearInterval(timer);
}, []);
The previous answers weren't considering other states - wordIndex and lives and didn't include clear Intervals
It's advisable to use callback setState inside setIntervals and clear the interval on next useEffect call
const [counter, setCounter] = React.useState(10);
React.useEffect(() => {
let timer = setInterval(() => {
// It's advisable to use callback setState inside setIntervals
setCounter(prev => {
if (prev !== 0) return prev - 1;
setWordIndex(wordIndex + 1);
setLives(lives - 1);
life.play();
return 10;
});
}, 1000);
// And clear the interval next useEffect call
return () => clearInterval(timer);
}, [wordIndex, lives]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.