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

139
Visualizações
(React rendering) SetInterval just keeps going faster and unpredictable

I'm trying to implement a simple timer that just counts up continuously every second. I'm using react to render the result. The code is only a few lines and makes sense from what I've been reading. It adds and renders properly for the first 6 seconds; however, it just starts displaying random numbers after the 7th or 8th, OR the timer becomes erroneous and updates every random second. My code is as follows, am I doing something wrong? Thanks!

import React, {useState} from 'react';

function App() {

  const [count, setCount] = useState(0); 

  setInterval(()=>{setCount(count + 1)}, 1000)

  return (
    <div className="welcome">
      {count}
    </div>
  );
}

export default App;

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

that because it start a new one every time the component rerender use this instead

import React, {useState} from 'react';

function App() {

  const [count, setCount] = useState(0); 
  const timer = useRef(null);


useEffect(() => {
  timer.current = setInterval(()=>{setCount(count + 1)}, 1000);
  return () => {
    if(timer.current !== null) clearInterval(timer.current);
  };
}, []);

  return (
    <div className="welcome">
      {count}
    </div>
  );
}

export default App;


about 4 years ago · Juan Pablo Isaza Relatório

0

Your code has some issues, as do the other answers. They can be summarized in three points:

  1. If you want to use Interval or Timeout (or any other event listener), you need to do this inside a useEffect, so you won't add a new listener in each render.

  2. If you use an useEffect for it, you'll need to clean up the Interval/Timeout (or any other listener) to avoid memory leaks.

  3. We can avoid using the count variable inside the dependencies array by using setCount(oldCount => oldCount + 1). Citing React documentation:

If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.

If you ignore step 3 by using count as a hook-dependency, you will create and clean up an Interval in each render - this is unnecessary.
If you decide to just use setCount(count + 1) without adding it to the dependency array, you're using hooks wrong, count will always have the same value (the initial one).

I added a button to force a re-render in the example below to show that the count keeps going as expected.

function App() {
  const [count, setCount] = React.useState(0);
  const [forced, setForced] = React.useState(0);

  React.useEffect(() => {
    // Store the interval id in a const, so you can cleanup later
    const intervalId = setInterval(() => {
      setCount(oldCount => oldCount + 1);
    }, 1000);
    
    return () => {
      // Since useEffect dependency array is empty, this will be called only on unmount
      clearInterval(intervalId);
    };
  }, []);
  
  function forceRerender() {
    setForced(oldForced => oldForced + 1);
  }

  return (
    <div>
      <p>{count} seconds</p>
      <p>Forced re-renders: {forced}</p>
      <button onClick={forceRerender}>Force a re-render</button>
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector('#app'));
<div id="app"></div>
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

about 4 years ago · Juan Pablo Isaza Relatório

0

The setInterval call should be put inside a useEffect hook and cleanup should be done too:

import React, { useState, useEffect, useRef } from "react";

function App() {
  const [count, setCount] = useState(0);
  const ref = useRef();

  useEffect(() => {
    ref.current = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => {
      clearInterval(ref.current);
    };
  }, [count]);

  return <div className="welcome">{count}</div>;
}

export default App;
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