実現したいこと
Reactでカウントダウンタイマーを作りたいです。ただし、タイマーがカウントする値は、1回目、2回目、3回目では変化します。
例えば、1回目のカウントは3秒、2回目のカウントは5秒、3回目のカウントは10秒といった具合です。
画面上では、スタートを押すと、「3,2,1,0→5,4,3,2,1,0→10,9,8,7,6,5,4,3,2,1,0(自動的に止まる)」
といった表示にしたいです。
何回目のカウントで、何秒カウントするかは、コンポーネントに配列で渡すとします。
前提
ReactとTailwindcssでタイマーコンポーネントを作成しています。
発生している問題・エラーメッセージ
タイマーをスタートさせると、2回目のカウントで、3秒から5秒には切り替わるのですが、3回目のカウントで10秒に切り替わらず、5秒のカウントになってしまいます。
おそらく、タイマーのカウントが0になった時の処理が適切でないと考えています。useStateの使い方を間違えていると思うのですが、どこを修正したらよいかが分かりません。
該当のソースコード
import { useState, useRef } from "react"; const timerInfo = [3, 5, 10]; function Timer() { const [timerIndex, setTimerIndex] = useState(0); const [seconds, setSeconds] = useState(timerInfo[timerIndex]); const [isActive, setIsActive] = useState(false); const countRef = useRef(null); const startTimer = () => { setIsActive(true); countRef.current = setInterval(() => { setSeconds((seconds) => { if (seconds <= 0) { if (timerIndex === timerInfo.length) { resetTimer(); return 0; } else { updateTimer(); const newTimerIndex = timerIndex + 1; return timerInfo[newTimerIndex]; } } else { return seconds - 1; } }); }, 1000); }; const stopTimer = () => { clearInterval(countRef.current); setIsActive(false); }; const updateTimer = () => { clearInterval(countRef.current); const newTimerIndex = timerIndex + 1; setTimerIndex((timerIndex) => timerIndex + 1); startTimer(); }; const resetTimer = () => { clearInterval(countRef.current); setIsActive(false); setTimerIndex(0); }; return ( <div className="flex flex-col items-center justify-center h-screen"> <div className="text-6xl font-bold">{seconds}</div> <div className="flex mt-5"> <button className={`px-4 py-2 font-bold text-white ${ isActive ? "bg-red-600" : "bg-green-600" } mr-2`} onClick={isActive ? stopTimer : startTimer} > {isActive ? "ストップ" : "スタート"} </button> <button className="px-4 py-2 font-bold text-white bg-gray-600" onClick={resetTimer} > リセット </button> </div> </div> ); } function App() { return ( <div className="App"> <h1 className="text-orange-400">タイマーアプリ</h1> <div> <Timer /> </div> </div> ); } export default App;

回答2件
あなたの回答
tips
プレビュー