React开发Pomodoro番茄钟休息时段会话数累加异常如何修复
问题根因
- 计数触发时机不符合预期:只有完整走完「工作时段+休息时段」的完整周期才需要给session加1,原有逻辑和状态切换耦合,会在一个周期内触发两次计数逻辑
- useEffect依赖冗余:你把
session加入了useEffect的依赖数组,每次调用setSession更新session值时都会触发useEffect重新执行,进一步导致计数被重复触发,这就是原本加1会实际加2的核心原因
修复后完整代码
import React, { useState, useEffect } from "react"; function Pomodoro() { const [minutes, setMinutes] = useState(25); const [seconds, setSeconds] = useState(0); const [displayMessage, setDisplayMessage] = useState(false); const [session, setSession] = useState(1); useEffect(() => { let interval = setInterval(() => { clearInterval(interval); if (seconds === 0 && minutes !== 0) { setSeconds(59); setMinutes(minutes - 1); } else if (seconds === 0 && minutes === 0) { // 通过setSession回调取最新session值,无需把session加入依赖 let breakTime; setSession(prevSession => { breakTime = prevSession % 4 === 0 ? 14 : 4; return prevSession; }) const nextMinutes = displayMessage ? 24 : breakTime; const nextSeconds = 59; // 仅休息结束切换回工作时段时加1,对应完整周期结束 if (displayMessage) { setSession(prev => prev + 1); } setSeconds(nextSeconds); setMinutes(nextMinutes); setDisplayMessage(!displayMessage); } else { setSeconds(seconds - 1); } }, 1000); // 从依赖中移除session,避免更新session触发useEffect重跑 }, [seconds, displayMessage, minutes]); const timerMinutes = minutes < 10 ? `0${minutes}` : minutes; const timerSeconds = seconds < 10 ? `0${seconds}` : seconds; return ( <div className="pomodoro"> <div> Session: {session} </div> <div className="message"> {displayMessage && <div>Break time! New Session starts in:</div>} </div> <div className="timer"> {timerMinutes}:{timerSeconds} </div> </div> ); } export default Pomodoro;
核心调整说明
- 从useEffect依赖数组中移除了
session,计算休息时间时通过setSession的函数式回调拿到最新的session值,不会触发useEffect重复执行 - 仅在
displayMessage为true(即休息时段结束)时执行session加1,刚好对应一个完整的「工作+休息」周期结束,符合预期计数逻辑
内容的提问来源于stack exchange,提问作者Gateway2Music
相关产品推荐
相关产品推荐

