-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathuseTimer.ts
64 lines (53 loc) · 1.48 KB
/
useTimer.ts
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
import { useEffect, useMemo, useRef, useState } from 'react'
import { logger } from '../../../utils'
const log = logger.child({ prefix: 'useTimer' })
type Time = [house: number, minute: number, second: number]
function formatTime(time: number): Time {
const house = Math.floor(time / 3600)
const minute = Math.floor((time / 60) % 60)
const second = Math.floor(time % 60)
return [house, minute, second]
}
type UseTimeReturn = {
time: Time
isDone: boolean
done: (time: Time) => void
restart: () => void
}
/**
* 计时器钩子
* @returns 返回当前累计的时间 `time`;是否已结束 `isDone`;结束当前计时函数 `done`;重新开始函数 `restart`
*/
const useTimer = (): UseTimeReturn => {
const start = useRef(new Date())
const [isDone, setIsDone] = useState(false)
const [value, setValue] = useState(0)
const time = useMemo(() => {
return formatTime(value)
}, [value])
useEffect(() => {
let timer: ReturnType<typeof setInterval>
if (!isDone) {
timer = setInterval(async () => {
setValue(Math.floor((Date.now() - start.current.valueOf()) / 1000))
}, 100)
}
return () => {
if (timer) {
clearInterval(timer)
}
}
}, [isDone])
const restart = () => {
log.debug('重新开始计时')
setIsDone(false)
start.current = new Date()
setValue(0)
}
const done = () => {
log.debug('结束计时')
setIsDone(true)
}
return { time, isDone, done, restart }
}
export { useTimer }