Sin embargo, estaba tratando de hacer un contador de cronómetro cuando llamo a la función "startTimer", la función setInterval se activa antes de setStartTime (se activa después de hacer clic en el botón de inicio por segunda vez).
import React from "react"; import { useState, useRef } from "react"; import RunButton from "./RunButton"; const RunTimer = () => { const [timerOn, setTimerOn] = useState(false); const [startTime, setStartTime] = useState(0); const [timerTime, setTimerTime] = useState(0); const timerInterval = useRef(null); const startTimer = () => { setTimerOn(true); setStartTime(Date.now() - timerTime); timerInterval.current = setInterval(() => { setTimerTime(Date.now() - startTime); }, 1000); }; const stopTimer = () => { setTimerOn(false); clearInterval(timerInterval); }; const resetTimer = () => { setStartTime(0); setTimerTime(0); }; let seconds = Math.floor(timerTime / 1000) % 60; let minutes = Math.floor(timerTime / 1000 / 60) % 60; return ( <div className="text-6xl font-medium text-center"> {minutes < 10 ? `0${minutes}` : minutes}: {seconds < 10 ? `0${seconds}` : seconds} <div className="flex gap-10 justify-around"> <RunButton title="start" action={startTimer} /> <RunButton title="stop" color="red" action={stopTimer} /> <RunButton action={resetTimer} color="yellow" title="reset" /> </div> </div> ); }; export default RunTimer; <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>Todavía no entiendo por qué necesita Date.now() para crear un cronómetro.
Lo que está mal con:
const RunTimer = () => { const [time, setTime] = useState(0); const timerInterval = useRef(null); const startTimer = () => { if (!timerInterval.current) { timerInterval.current = setInterval(() => { setTime((t) => t + 1000); }, 1000); } }; const stopTimer = () => { clearInterval(timerInterval.current); timerInterval.current = null; }; const resetTimer = () => { setTime(0); }; const seconds = Math.floor(time / 1000) % 60; const minutes = Math.floor(time / 1000 / 60) % 60; useEffect(() => { return () => clearInterval(timerInterval.current); }, []); return ( <div className="text-6xl font-medium text-center"> {minutes < 10 ? `0${minutes}` : minutes}: {seconds < 10 ? `0${seconds}` : seconds} <div className="flex gap-10 justify-around"> <button title="start" onClick={startTimer}> start </button> <button title="start" onClick={stopTimer}> stop </button> <button title="start" onClick={resetTimer}> reset </button> </div> </div> ); };