DEV Community

Discussion on: How to Create a Simple React Countdown Timer

Collapse
 
arpan_banerjee7 profile image
Arpan Banerjee

I think you just complicated the things unnecessarily, always remember this rule of thumb

  • whenever you want to update the state based on the previous state , pass a function to the setState() method, then react will make sure it will call the setState() with the latest value of the state variable.
import React from "react";
export default function App() {
  const [counter, setCounter] = React.useState(60);

  // Second Attempts
  React.useEffect(() => {
     counter>0 && setInterval(() => {
        setCounter((time)=>time-1);
      }, 1000);
  }, []);

  return (
    <div className="App">
      <div>Countdown: {counter}</div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

This solution works, but it has a problem, the countdown never stops.
To make it stop at 0, we will make use of useRef hook, it will store the reference to the setInterval, whihc we can clear when the timer is 0.The complete solution would look like this.

import React from "react";
export default function App() {
  const [timer, setTimer] = React.useState(10);
  const id =React.useRef(null);
  const clear=()=>{
  window.clearInterval(id.current)
}
  React.useEffect(()=>{
     id.current=window.setInterval(()=>{
      setTimer((time)=>time-1)
    },1000)
    return ()=>clear();
  },[])

  React.useEffect(()=>{
    if(timer===0){
      clear()
    }

  },[timer])


  return (
    <div className="App">

     <div>Time left : {timer} </div>

    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

codesandbox.io/s/reverent-bash-bxrnv

please let me know your thoughts on this.

Collapse
 
zhiyueyi profile image
Zhiyue Yi

Your solution is more intuitive than mine. Nice one!

Collapse
 
arpan_banerjee7 profile image
Arpan Banerjee

Thank you!

Collapse
 
hussamkhatib profile image
mohammed hussam

hey this is a very nice implementation , but consider i want the timer to completely stop at 0 , and then we want the countdown again , if we change the value of timer then it won't do anything.
Any idea how we can overcome this

Collapse
 
ankit_choudhary profile image
ankit kumar • Edited

Hi Arpan , i think if you pass Timer as dependency in useEffect, that will do the job simply.
you dont need to use useRef and 2nd useEffect.
let me know your thoughts.

React.useEffect(() => {
const TimerInt = timer >0 && setInterval(() => {
setCounter((time)=>time-1);
}, 1000);
return () => {
clearInterval(TimerInt)
}
}, [timer]);