Aprendí javascript, reaccioné e intenté contar de 10 a 0, pero de alguna manera el temporizador solo llegaba a 9, pensé que setInterval se ejecutaba cada n vez que configuramos (n puede ser 1000ms, 2000ms...)
Aquí está el código
import "./styles.css"; import React, { useState } from "react"; export default function App() { const [time, setTime] = useState(10); const startCountDown = () => { const countdown = setInterval(() => { setTime(time - 1); }, 1000); if (time === 0) { clearInterval(countdown); } }; return ( <div> <button onClick={() => { startCountDown(); }} > Start countdown </button> <div>{time}</div> </div> ); }Aquí está el código: https://codesandbox.io/s/class-component-ujc9s?file=/src/App.tsx:0-506
Por favor explique esto, estoy tan confundido, gracias
time es el valor leído del estado (que es el valor predeterminado que se pasa a useState ) cada vez que se representa el componente.
Cuando haces clic, llamas a setInterval con una función que se cierra durante el time desde el último renderizado.
Cada vez que el componente se procesa a partir de ese momento, lee un nuevo valor de time del estado.
Sin embargo, el intervalo sigue funcionando con la variable original , que sigue siendo 10 .
Las funciones de estado le darán el valor actual del estado si pasa una devolución de llamada. Así que usa eso en lugar de la variable cerrada.
setTime(currentTime => currentTime - 1);Simplemente use la devolución de llamada en su función setState porque, de lo contrario, reaccionar funciona con el valor anterior del tiempo:
import "./styles.css"; import React, { useState } from "react"; export default function App() { const [time, setTime] = useState(10); const startCountDown = () => { const countdown = setInterval(() => { setTime((prevTime)=>prevTime - 1); }, 1000); if (time === 0) { clearInterval(countdown); } }; return ( <div> <button onClick={() => { startCountDown(); }} > Start countdown </button> <div>{time}</div> </div> ); } editar: puede almacenar su identificador de intervalo en useRef, porque useRef persiste a través de la repetición y no causará otra repetición, y luego verifique el tiempo en useEffect con el time en dependencia
import "./styles.css"; import React, { useEffect, useRef, useState } from "react"; export default function App() { const [time, setTime] = useState(10); const interval = useRef(0); const startCountDown = () => { interval.current = setInterval(() => { setTime((prevTime) => prevTime - 1); }, 1000); }; useEffect(() => { if (time === 0) { clearInterval(interval.current); } }, [time]); return ( <div> <button onClick={() => { startCountDown(); }} > Start countdown </button> <div>{time}</div> </div> ); }sandbox de trabajo: https://codesandbox.io/s/class-component-forked-lgiyj?file=/src/App.tsx:0-613