I'm trying to implement a 5 seconds countdown using hooks in react. On others answers, the solution is to implement setInterval with React.useEffect, but I'd like to let the final user to trigger the countdown with a button. Then, at the end of the coundown, execute a function.
I managed the show the timer, but I didn't manage to execute a function when the timer is 0. In the following case, the console.log is not triggered.
function Test(){
const [timeLeft, setTimeLeft] = useState(null);
useEffect(() => {
// exit early when we reach 0
if (!timeLeft) return;
if(timeLeft===0){
console.log("TIME LEFT IS 0");
setTimeLeft(null)
}
// save intervalId to clear the interval when the
// component re-renders
const intervalId = setInterval(() => {
setTimeLeft(timeLeft - 1);
}, 1000);
// clear interval on re-render to avoid memory leaks
return () => clearInterval(intervalId);
// add timeLeft as a dependency to re-rerun the effect
// when we update it
}, [timeLeft]);
return (
<React.Fragment>
{timeLeft}
<Button onClick={()=>setTimeLeft(5)} className={classes.button}>
TEST
</Button>
</React.Fragment>
})
}
My mistake. The 0 will trigger the return in the useEffect. I had just to move the check above it:
function Test(){
const [timeLeft, setTimeLeft] = useState(null);
useEffect(() => {
if(timeLeft===0){
console.log("TIME LEFT IS 0");
setTimeLeft(null)
}
// exit early when we reach 0
if (!timeLeft) return;
// save intervalId to clear the interval when the
// component re-renders
const intervalId = setInterval(() => {
setTimeLeft(timeLeft - 1);
}, 1000);
// clear interval on re-render to avoid memory leaks
return () => clearInterval(intervalId);
// add timeLeft as a dependency to re-rerun the effect
// when we update it
}, [timeLeft]);
return (
<React.Fragment>
{timeLeft}
<Button onClick={()=>setTimeLeft(5)} className={classes.button}>
TEST
</Button>
</React.Fragment>
})
}