本文译自:30-seconds-of-react。React 30 秒速学:全篇中文翻译、学习,地址:30-seconds-of-react-zh_CN-umi,所有案例进行分析、注释、上线。
渲染倒数计时器,在达到零时打印消息。
- 使用对象解构来设置
hours
,minutes
和seconds
prop 的默认值。 - 使用
React.useState()
钩子来创建time
,paused
和over
状态变量,并将它们的值分别设置为传递的props,false
和false
的值。 - 创建一个方法
tick
,它根据当前值更新time
的值(即将时间减少一秒)。 - 如果
paused
或over
是true
,tick
将立即返回。 - 创建一个方法
reset
,将所有状态变量重置为其初始状态。 - 使用
React.useEffect()
钩子通过使用setInterval()
每秒调用tick
方法,并在卸载组件时使用clearInterval()
进行清理。 - 使用
<div>
用time
状态变量的文本表示形式包装<p>
元素,以及分别暂停/取消暂停和重启计时器的两个<button>
元素。 - 如果
over
为true
,计时器将显示一条消息,而不是time
的值。
import React from "react";
function CountDown({ hours = 0, minutes = 0, seconds = 0 }) {
const [paused, setPaused] = React.useState(false);
const [over, setOver] = React.useState(false);
// time 默认值是一个 object
const [time, setTime] = React.useState({
hours: parseInt(hours),
minutes: parseInt(minutes),
seconds: parseInt(seconds)
});
const tick = () => {
// 暂停,或已结束
if (paused || over) return;
if (time.hours === 0 && time.minutes === 0 && time.seconds === 0)
setOver(true);
else if (time.minutes === 0 && time.seconds === 0)
setTime({
hours: time.hours - 1,
minutes: 59,
seconds: 59
});
else if (time.seconds === 0)
setTime({
hours: time.hours,
minutes: time.minutes - 1,
seconds: 59
});
else
setTime({
hours: time.hours,
minutes: time.minutes,
seconds: time.seconds - 1
});
};
// 重置
const reset = () => {
setTime({
hours: parseInt(hours),
minutes: parseInt(minutes),
seconds: parseInt(seconds)
});
setPaused(false);
setOver(false);
};
React.useEffect(() => {
// 执行定时
let timerID = setInterval(() => tick(), 1000);
// 卸载组件时进行清理
return () => clearInterval(timerID);
});
return (
<div>
<p>{`${time.hours
.toString()
.padStart(2, "0")}:${time.minutes
.toString()
.padStart(2, "0")}:${time.seconds.toString().padStart(2, "0")}`}</p>
<div>{over ? "Time's up!" : ""}</div>
<button onClick={() => setPaused(!paused)}>
{paused ? "Resume" : "Pause"}
</button>
<button onClick={() => reset()}>Restart</button>
</div>
);
}
复制代码
例子
export default function() {
return <CountDown hours="1" minutes="45" />;
}
复制代码