React - 5 Seconds Countdown with Hooks

React - 5 Seconds Countdown with Hooks

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>
 })
}
2

1 Answer

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>
 })
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Robert Thorne
Author

Robert Thorne

Robert Thorne covers electric vehicle innovations, autonomous driving systems, global mobility trends, and automotive engineering developments.