Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

157
Vistas
Best way to use setInterval inside React useEffect in countdown timer

newbie to Javascript & React, trying to learn my way through React by building small projects. I'm working on a countdown timer right now, and I'm wondering if there's a better way of handling the pause/stop logic.

Right now, I'm calling setInterval() when my component is no longer in a "Paused" !paused state, and returning a cleanup() function to clear the interval. When I console logged it, it only cleared interval on pause/start.

However, I want to add functionality to automatically stop the timer once it hits zero, which requires adding duration state as a second dependency. When I logged this to console, I realized that my setDuration and clearInterval was now running at every interval, rather than only on the pause/start (it looks like it's calling setInterval() at every "tick" now.

My question is - is this a problem? And is there a better way to do this?

function Timer(props) {
  const [duration, setDuration] = useState(10);
  const [paused, setPaused] = useState(true);

  useEffect(() => {
    let timerId;
    if (!paused) {
      timerId = setInterval(() => {
        setDuration(prev => prev - 1);
      }, 1000);
      // console.log(timerId);
    }

    if (duration === 0) {
      // console.log(`Time's up`);
      clearInterval(timerId);
    }

    return function cleanup() {
      // console.log(`Clearing ${timerId}`);
      clearInterval(timerId);
    };
  }, [paused, duration]);

  const handleClick = (e) => {
    !paused ? setPaused(true) : setPaused(false);
  };

  return (
    <>
      <h3>{duration}</h3>
      <Button paused={paused} onClick={handleClick} />
    </>
  );
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

In your code, duration is changing on every interval and because it is passed as a parameter in dependecy array, it is triggering useEffect on each interval which is causing it to the setDuration and clearInterval to run at each interval.

you can use ternary operator to check if the duration is less than zero then you can automatically set the duration to zero by using setDuration(0)

function Timer(props) {
      const [duration, setDuration] = useState(10);
      const [paused, setPaused] = useState(true);
    
      useEffect(() => {
        let timerId;
        if (!paused) {
          timerId = setInterval(() => {
            setDuration((prev) => prev - 1);
          }, 1000);
          console.log(timerId);
        }
    
        return function cleanup() {
          console.log(`Clearing ${timerId}`);
          clearInterval(timerId);
        };
      }, [paused]);
    
      const handleClick = (e) => {
        !paused ? setPaused(true) : setPaused(false);
      };
    
      return (
        <>
          {duration >= 0 ? <h3>{duration}</h3> : setDuration(0)}
          <button paused={paused} onClick={handleClick} />
        </>
      );
    }

Play around with the code here

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda