Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

159
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda