Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

241
Views
¿Cómo obtener setInterval en React para cambiar una variable de estado?

Quiero que el siguiente código comience la cuenta regresiva desde un número después de que un usuario inicie sesión.

El siguiente código muestra 0 simples en el archivo console.log cada segundo, pero no parece establecer la variable de estado secondsLeft en 8, ni cuenta esta variable hacia atrás.

 const [secondsLeft, setSecondsLeft] = useState(0);

...

 const handleButton = async () => { const response = await fetch('http://localhost:5001/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); setUsername(''); setPassword(''); if (response.ok) { const data = await response.json(); setCurrentUser(prev => ({ ...prev, ...data.user })); setMessage(`User: ${currentUser.firstName}`); setSecondsLeft(8); setInterval(() => { setSecondsLeft(prev => secondsLeft -1); console.log(secondsLeft); }, 1000); } else { setMessage('bad login'); } }

¿Cómo puedo obtener setInterval para disminuir el valor de los secondsLeft cada segundo?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Esta es una trampa muy común en React. Usted, comprensiblemente, parece asumir que setSecondsLeft surte efecto inmediatamente, pero no es así. Por lo tanto, secondsLeft no será 8 para empezar. Hay otro problema de que secondsLeft no se actualiza en su intervalo. Esto debería funcionar en su lugar:

 setSecondsLeft(8); setInterval(() => { setSecondsLeft(prev => { console.log(prev); return prev - 1; }); }, 1000);
about 4 years ago · Juan Pablo Isaza Report

0

En realidad funciona, pero se ve en la consola 8 cada vez que se ejecuta la devolución de llamada de setIntervall, porque solo accede al valor inicial de segundos restantes y no reconoce la actualización de segundos restantes en actualizaciones posteriores. Puede ejecutar el siguiente ejemplo y ver cómo se actualiza el estado cada vez que se ejecuta la devolución de llamada de Time setInterval, pero en la consola siempre ve 0.

 function App() { const [secondsLeft, setSeconds] = React.useState(0); let timerId = null; const handleClick = () => { setSeconds(8); timerId = setInterval(()=> { console.log(secondsLeft) setSeconds(prev => prev - 1); }, 1000) }; React.useEffect(()=> { return ()=> clearInterval(timerId) }, []) return ( <div> <h2>{secondsLeft}</h2> <button onClick={handleClick}>Start interval</button> </div> ); } ReactDOM.render(React.createElement(App, {}), document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script> <div id="root"></div>

about 4 years ago · Juan Pablo Isaza Report

0

Traté de hacer las cosas de la manera tradicional,

 useEffect(() => { setInterval(() => { console.log("update", st); setSt((prev) => prev + 1); }, 500); }, []);

Pero esto no funciona porque durante la ejecución de useState en el primer render, setInterval guarda una copy of prev para sí mismo que intenta actualizar una y otra vez, por ejemplo: setSt(prev => prev+1) pero desde prev siempre es = 1 debido al cierre que tiene para sí mismo, el valor realmente no se actualiza.


Luego traté de usar useCallback hook que vuelve a representar la function en el cambio de dependencia y, por lo tanto, brindó prev como dependencia, pero lamentablemente eso tampoco funcionó probablemente debido a la misma razón que la anterior pero por diferentes medios.

Puede ver la forma en que lo intenté en el código comentado de codesandbox .


Por fin, probé mis manos creando un setIntervalHack que puede funcionar de manera similar a setInterval, pero no es realmente un setInterval.

Aquí están los pasos que seguí.

  • Puede pensar en setInterval as a recursive que se ejecuta una y otra vez después de un intervalo , pero el inconveniente es que no podemos pasarle un argumento debido a que la actualización se vuelve obsoleta.
  • Entonces, pasé un argumento a setIntervalHack que representa el nuevo estado con el que se actualizará.
  • Para esperar un tiempo, usé promesas para await a que se ejecutara la recursividad nuevamente y en el argumento de recordar la función recursiva setIntervalHack , pasé (currentState+1)

y esta es la forma en que traté de lograr la funcionalidad similar de setInterval

Aquí está el enlace al código https://codesandbox.io/s/happy-swartz-ikqdn?file=/src/focus.js

Nota: puede ir a /focus route en codesandbox's browser y abrir la consola

PD: Hice un incremento en el contador, no el decremento. Puede hacer lo mismo disminuyendo en cada recursión

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!