React+Typescript实现倒计时Hook的方法
首先对setInterval做了Hook化封装
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?.immediateconst timerRef = useRef<() => void>()timerRef.current = fnuseEffect(() => {if (delay === undefined || delay === null) {return}if (immediate) {timerRef.current?.()}const timer = setInterval(() => {timerRef.current?.()}, delay)return () => {clearInterval(timer)}}, [delay])}export default useInterval
【React+Typescript实现倒计时Hook的方法】实现倒计时Hook
import { useState, useEffect, useRef, useMemo } from 'react'import { useInterval } from './'interface ITime {/** 当前时间 */currentTime?: number/** 结束时间 */endTime?: number/** 另一种方式,不传当前时间和结束时间,直接传时间差 */differTime?: number}interface ICbTime {d: numberh: numberm: numbers: 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 } = optionsconst [diffTime, setDiffTime] = useState(0)/** 组件接收到参数时的时间 */const entryTime = useRef(0)/** 当前倒计时要求的时间差 */const maxTime = useRef (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 - currentTimeif (maxTime.current <= 0 && noImmediate) {isImplementCb.current = false}setDiffTime(maxTime.current)}}, [currentTime, endTime, differTime])useInterval(() => {const curtTimes = new Date().getTime()const TimeDifference = curtTimes - entryTime.currentsetDiffTime(maxTime.current - TimeDifference)},diffTime <= 0 ? null : 1000)const timeObj = useMemo(() => {const time = diffTime > 0 ? diffTime / 1000 : 0const 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 (距离任务结束 {d}天{h < 10 ? '0' + h : h}:{m < 10 ? '0' + m : m}:{s < 10 ? '0' + s : s})}
到此这篇关于React+Typescript实现倒计时Hook的方法的文章就介绍到这了,更多相关React+Typescript实现倒计时 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM