这篇文章主要介绍“怎么用React+Typescript实现倒计时的功能”,在日常操作中,相信很多人在怎么用React+Typescript实现倒计时的功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用React+Typescript实现倒计时的功能”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
import { useEffect, useRef } from 'react'
/**
* interTerval hooks组件
* @param fn 执行函数
* @param delay 时间
* @param options immediate为true时,先立即执行一次fn函数后再执行定时器
*/
function useInterval(
fn: () => void,
delay: number | null | undefined,
options?: {
immediate?: boolean
}
): void {
const immediate = options?.immediate
const timerRef = useRef<() => void>()
timerRef.current = fn
useEffect(() => {
if (delay === undefined || delay === null) {
return
}
if (immediate) {
timerRef.current?.()
}
const timer = setInterval(() => {
timerRef.current?.()
}, delay)
return () => {
clearInterval(timer)
}
}, [delay])
}
export default useInterval
实现倒计时Hook
import { useState, useEffect, useRef, useMemo } from 'react'
import { useInterval } from './'
interface ITime {
/** 当前时间 */
currentTime?: number
/** 结束时间 */
endTime?: number
/** 另一种方式,不传当前时间和结束时间,直接传时间差 */
differTime?: number
}
interface ICbTime {
d: number
h: number
m: number
s: number
}
/**
* 倒计时hooks
* @param options 时间对象
* @param cb 倒计时完成时执行的回调函数
* @param noImmediate 时间传进来满足执行回调条件时,是否立即执行回调,默认false执行
*/
function useCountDown(
options: ITime,
cb?: () => void,
noImmediate?: boolean
): ICbTime {
const { currentTime = 0, endTime = 0, differTime = 0 } = options
const [diffTime, setDiffTime] = useState(0)
/** 组件接收到参数时的时间 */
const entryTime = useRef<number>(0)
/** 当前倒计时要求的时间差 */
const maxTime = useRef<number>(0)
/** 是否可以执行回调 */
const isImplementCb = useRef(false)
useEffect(() => {
if (!isImplementCb.current) {
isImplementCb.current = true
}
if ((currentTime > 0 && endTime > 0) || differTime > 0) {
entryTime.current = new Date().getTime()
maxTime.current = differTime > 0 ? differTime : endTime - currentTime
if (maxTime.current <= 0 && noImmediate) {
isImplementCb.current = false
}
setDiffTime(maxTime.current)
}
}, [currentTime, endTime, differTime])
useInterval(
() => {
const curtTimes = new Date().getTime()
const TimeDifference = curtTimes - entryTime.current
setDiffTime(maxTime.current - TimeDifference)
},
diffTime <= 0 ? null : 1000
)
const timeObj = useMemo(() => {
const time = diffTime > 0 ? diffTime / 1000 : 0
const d = Math.floor(time / (24 * 60 * 60))
const h = Math.floor((time / (60 * 60)) % 24)
const m = Math.floor((time / 60) % 60)
const s = Math.ceil(time % 60)
if (diffTime <= 0 && isImplementCb.current) {
/**
* setTimeout用于解决react报错问题:
* annot update during an existing state transition (such as within `render`).
* Render methods should be a pure function of props and state.
*/
setTimeout(() => {
cb?.()
}, 0)
}
return { d, h, m, s }
}, [diffTime])
return timeObj || ({} as ICbTime)
}
export default useCountDown
写个demo看一下效果?
const TimeArea = () => {
const { d, h, m, s } = useCountDown(
{
currentTime: 1631262176333,
endTime: 1831062176333
},
() => {
alert('倒计时结束')
}
)
return (
<div style={{ width: '200px', height: '200px' }}>
距离任务结束 {d}天<i>{h < 10 ? '0' + h : h}</i>:
<i>{m < 10 ? '0' + m : m}</i>:<i>{s < 10 ? '0' + s : s}</i>
</div>
)
}
到此,关于“怎么用React+Typescript实现倒计时的功能”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。