有点难弄的计时器

Posted by gyn on 2022-08-07

在前端页面开发中,偶尔需要展示不同的计时或时间显示方式,本文将给出三种类型的相关示例。(仍在持续更新中…)

计时器 (Stopwatch)

通过useStateuseRefinterval实现的计时器,点击Start开始计时,点击Stop结束计时。计时器显示格式hh:mm:ss,当然,也可以通过修改getTimeString来显示你想要的计时器格式。完整代码可在CodeSandbox上查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
const StopWatch = () => {
const [startTime, setStartTime] = useState(null);
const [now, setNow] = useState(null);
const intervalRef = useRef(null);

const handleStart = () => {
setStartTime(Date.now());
setNow(Date.now());

clearInterval(intervalRef.current);
intervalRef.current = setInterval(() => {
setNow(Date.now());
}, 10);
};

const handleStop = () => {
clearInterval(intervalRef.current);
};

const timeString = getTimeString(now, startTime);

return (
<>
<h1>Time passed: {timeString}</h1>
<Button type="primary" shape="round" onClick={handleStart}>
Start
</Button>
<Button
type="primary"
shape="round"
danger
className="stop-btn"
onClick={handleStop}
>
Stop
</Button>
</>
);
};

export default StopWatch;

倒计时(Countdown)

通过useStateuseRef, useEffect, interval实现的计时器,点击Start开始计时,点击Stop结束计时。完整代码可在CodeSandbox上查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const Timer = () => {
const initialSeconds = 10;
const [seconds, setSeconds] = useState(initialSeconds);
const [startFlag, setStartFlag] = useState(false);
const intervalRef = useRef(null);
useEffect(() => {
if (!startFlag) {
return;
}
intervalRef.current = setInterval(() => {
if (seconds > 1) {
setSeconds(seconds - 1);
}
if (seconds <= 1) {
setStartFlag(false);
setSeconds(initialSeconds);
clearInterval(intervalRef.current);
}
}, 1000);
return () => {
clearInterval(intervalRef.current);
};
}, [startFlag, seconds]);

const handleStart = () => {
setSeconds(initialSeconds);
setStartFlag(true);
};

const handleStop = () => {
setStartFlag(false);
setSeconds(initialSeconds);
clearInterval(intervalRef.current);
};

return (
<div className="App">
{seconds === 0 ? (
<h1>Countdown: {initialSeconds}</h1>
) : (
<h1> Remaining: {seconds < 10 ? `0${seconds}` : seconds}</h1>
)}
<Button
type="primary"
shape="round"
onClick={handleStart}
disabled={startFlag}
>
Start
</Button>
<Button
type="primary"
shape="round"
disabled={!startFlag}
danger
onClick={handleStop}
>
Stop
</Button>
</div>
);
};

export default Timer;