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

156
Vistas
SetInterval "Stacking" on top of each other

I'm working on this project which uses setInterval and I'm having a little trouble understanding how setInterval works. The problem I'm having is that the each time I call setInterval the function seems to stack on top of each other resulting in the object appearing multiple times rapidly. I'm not sure what I'm doing wrong in this case. Can someone please help me out thanks.

const [hit, setHit] = useState(0)
const [count, setCount] = useState(0)
var timer = null
var funcCalls = 0
const hitSound = new Audio("/hit.wav")
useEffect(()=>{
    timer = setInterval(moveSquare, 2000)
},[])
function handleHit(){
    hitSound.play()
    setHit(hit+1)
    resetSquare()
}
function resetSquare(){
    clearInterval(timer)
    moveSquare()
    timer = setInterval(moveSquare, 2000)
}
function moveSquare(){
    const gameContainer = document.getElementById("game-container")
    const height = gameContainer.offsetHeight
    const width = gameContainer.offsetWidth
    const square = document.getElementById("square")
    square.style.top = (Math.random() * (height - 100)) + "px";
    square.style.left = (Math.random() * (width - 100)) + "px";
}
return (
    <>
    <section className='game-section'>
        <div className='counter'>
            {hit}
            {count}
        </div>
        <div className='game-container' id = "game-container">
            <div className="square" id = "square" onClick={handleHit}></div>
        </div>
    </section>
    </>
)
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

It's because the timer value isn't saved across renders so you can't cancel it.

var timer = null // <-- no
const [timer, setTimer] = useState(null) // <-- yes
...
// later in useEffect() and resetSquare()
// save the timer using setTimer(timer)
about 4 years ago · Juan Pablo Isaza Denunciar

0

Reason for that is elsewhere: your component (and/or and of its parent) is recreated. There are just few reasons in general but it's hard to point a specific line of code without debugging:

  • Either conditional rendering (e.g. showing spinner during request and after render element with children again)
  • Or different key prop is provided
  • Or by mistake you put component declaration(function or class or wrap into HOC) inside of other component's render code and every time parent is rerendered, component's declaration becomes referentially different

Another root cause: your useEffect does not have cleanup. While it should. And even without first reason, you would not have multiple concurrent timers but you still would have timer that would not stop when you're navigating away.

useEffect(()=>{
    timer = setInterval(moveSquare, 2000)
    return () => clearInterval(timer);
},[])

More on cleanup in official docs: https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup

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