有没有办法在 React 中遍历计时器?
Is there a way to iterate through a timer in React?
我正在尝试使用 Hooks 创建番茄钟计时器,并且我已经使用 useState 和 useEffect 设置了基本功能。我有一个 25 分钟的倒计时计时器,每次倒数到 0 时,它都会启动一个 5 分钟的休息计时器。我现在想弄清楚的是如何创建一个迭代,说“每 4 次计时器达到 0,将休息时间从 5 分钟更改为 15 分钟,然后再回到 5 分钟。”我想以这种方式创建会话,它会说第 4 个会话,然后它会回到第 1 个。但我真的不确定在这里做什么。
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) {
let minutes = displayMessage ? 24 : 4;
let seconds = 59;
setSeconds(seconds);
setMinutes(minutes);
setDisplayMessage(!displayMessage);
} else {
setSeconds(seconds -1);
}
}, 1000);
}, [seconds]);
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;
您使用计数器来跟踪已完成会话的方法似乎很有意义。如果你想每四次迭代使用不同的休息时间,你可以使用 remainder 运算符,如下所示:
let breakTime = (session % 4) === 0 ? 14 : 0;
然后,您只需确保每次完成会话时将 session
变量递增 1。这也意味着您只想在不“休息”时增加它,因此您必须确保防范这种情况。
使用我测试过的完整代码更新答案。请注意我所做的以下更改:
- 我只是以秒为单位跟踪计时器 - 这降低了内部的复杂性
useEffect
并且您可以从秒转换为其他格式(再次尝试使用余数运算符)
- 将周期长度移至常量
- 为清楚起见,将变量
displayMessage
重命名为 isOnBreak
import React, { useState, useEffect } from "react";
// Define the period lengths (in seconds)
const workTime = 2;
const shortBreakTime = 4;
const longBreakTime = 6;
function Pomodoro() {
const [seconds, setSeconds] = useState(workTime);
// Renamed this variable for clarity to indicate it is a boolean
const [isOnBreak, setIsOnBreak] = useState(false);
const [session, setSession] = useState(1);
useEffect(() => {
let interval = setInterval(() => {
clearInterval(interval);
if (seconds === 0) {
let breakTime = (session % 4 === 0) ? longBreakTime : shortBreakTime;
let seconds = !isOnBreak ? breakTime : workTime;
// A session is complete when work and break is done,
// so only increment when finishing a break
if (isOnBreak) setSession(session+1);
setSeconds(seconds);
setIsOnBreak(!isOnBreak);
} else {
setSeconds(seconds -1);
}
}, 1000);
}, [seconds]);
// Here you could convert from seconds to minutes and seconds or whatever time format you prefer
const timerSeconds = seconds < 10 ? `0${seconds}` : seconds;
return (
<div className="pomodoro">
<div>Session:{session} </div>
<div className="message">
{isOnBreak && <div>Break time! New Session starts in:</div>}
</div>
<div className="timer">
{timerSeconds}
</div>
</div>
);
}
我正在尝试使用 Hooks 创建番茄钟计时器,并且我已经使用 useState 和 useEffect 设置了基本功能。我有一个 25 分钟的倒计时计时器,每次倒数到 0 时,它都会启动一个 5 分钟的休息计时器。我现在想弄清楚的是如何创建一个迭代,说“每 4 次计时器达到 0,将休息时间从 5 分钟更改为 15 分钟,然后再回到 5 分钟。”我想以这种方式创建会话,它会说第 4 个会话,然后它会回到第 1 个。但我真的不确定在这里做什么。
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) {
let minutes = displayMessage ? 24 : 4;
let seconds = 59;
setSeconds(seconds);
setMinutes(minutes);
setDisplayMessage(!displayMessage);
} else {
setSeconds(seconds -1);
}
}, 1000);
}, [seconds]);
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;
您使用计数器来跟踪已完成会话的方法似乎很有意义。如果你想每四次迭代使用不同的休息时间,你可以使用 remainder 运算符,如下所示:
let breakTime = (session % 4) === 0 ? 14 : 0;
然后,您只需确保每次完成会话时将 session
变量递增 1。这也意味着您只想在不“休息”时增加它,因此您必须确保防范这种情况。
使用我测试过的完整代码更新答案。请注意我所做的以下更改:
- 我只是以秒为单位跟踪计时器 - 这降低了内部的复杂性
useEffect
并且您可以从秒转换为其他格式(再次尝试使用余数运算符) - 将周期长度移至常量
- 为清楚起见,将变量
displayMessage
重命名为isOnBreak
import React, { useState, useEffect } from "react";
// Define the period lengths (in seconds)
const workTime = 2;
const shortBreakTime = 4;
const longBreakTime = 6;
function Pomodoro() {
const [seconds, setSeconds] = useState(workTime);
// Renamed this variable for clarity to indicate it is a boolean
const [isOnBreak, setIsOnBreak] = useState(false);
const [session, setSession] = useState(1);
useEffect(() => {
let interval = setInterval(() => {
clearInterval(interval);
if (seconds === 0) {
let breakTime = (session % 4 === 0) ? longBreakTime : shortBreakTime;
let seconds = !isOnBreak ? breakTime : workTime;
// A session is complete when work and break is done,
// so only increment when finishing a break
if (isOnBreak) setSession(session+1);
setSeconds(seconds);
setIsOnBreak(!isOnBreak);
} else {
setSeconds(seconds -1);
}
}, 1000);
}, [seconds]);
// Here you could convert from seconds to minutes and seconds or whatever time format you prefer
const timerSeconds = seconds < 10 ? `0${seconds}` : seconds;
return (
<div className="pomodoro">
<div>Session:{session} </div>
<div className="message">
{isOnBreak && <div>Break time! New Session starts in:</div>}
</div>
<div className="timer">
{timerSeconds}
</div>
</div>
);
}