【发布时间】:2020-06-30 13:06:19
【问题描述】:
我正在我的 react-native 应用程序中实现倒计时,但有些东西无法正常工作。
倒计时似乎每分钟损失 1 秒(你可以在 gif 中看到,它在 33 和 31 之间跳跃)
这是代码:
import {
differenceInDays,
differenceInHours,
differenceInMinutes,
differenceInSeconds,
isBefore,
parseISO,
} from 'date-fns'
import { useEffect, useState } from 'react'
type CountdownResult = {
days: number
hours: number
minutes: number
seconds: number
}
const calculateInitialDuration = (endDate: string, today: Date): CountdownResult => {
const futureDate = new Date(endDate)
const days = differenceInDays(futureDate, today)
const hours = differenceInHours(futureDate, today) % 24
const minutes = differenceInMinutes(futureDate, today) % 60
const seconds = differenceInSeconds(futureDate, today) % 60
return { days, hours, minutes, seconds }
}
const EXPIREDRESULT: CountdownResult = { days: 0, hours: 0, minutes: 0, seconds: 0 }
// TODO: FIXME: sometimes the countdown jumps directly between 2 seconds
// even if the real time passed is 1 second
// this was happening before the refactor too
const useCountdown = (endDate: string): CountdownResult => {
const today = new Date()
const formattedEndDate = parseISO(endDate)
// doing this because at the beginning countdown seems stuck on the first second
// maybe there is a better solution for this problem
const initialCountdown = calculateInitialDuration(endDate, today)
initialCountdown.seconds++
const [time, setTime] = useState(isBefore(formattedEndDate, today) ? EXPIREDRESULT : initialCountdown)
useEffect(() => {
if (isBefore(formattedEndDate, today)) return
const intervalId = setInterval(() => {
setTime(calculateInitialDuration(endDate, today))
}, 1000)
return (): void => clearInterval(intervalId)
}, [time])
return time
}
export default useCountdown
endDate 是一个遵循 ISO 8601 格式的字符串。
我正在使用 date-fns 但我也尝试了基本的 javascript 实现,错误仍然相同。
另外一个奇怪的是倒计时,一开始,第一秒就卡住了一秒(这就是我创建initialCountdown变量的原因),但实际上我不喜欢这个解决方案。
有什么建议吗?错误在哪里?提前致谢。
【问题讨论】:
-
SetInterval()不保证每 1000 毫秒执行一次! -
感谢@phuzi 的评论,您有什么建议吗?不同的实现?
-
看我的回答 ;)
标签: javascript reactjs react-native