React+Typescript實(shí)現(xiàn)倒計(jì)時(shí)Hook的方法
首先對(duì)setInterval做了Hook化封裝👇
import { useEffect, useRef } from 'react'
/**
* interTerval hooks組件
* @param fn 執(zhí)行函數(shù)
* @param delay 時(shí)間
* @param options immediate為true時(shí),先立即執(zhí)行一次fn函數(shù)后再執(zhí)行定時(shí)器
*/
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
實(shí)現(xiàn)倒計(jì)時(shí)Hook
import { useState, useEffect, useRef, useMemo } from 'react'
import { useInterval } from './'
interface ITime {
/** 當(dāng)前時(shí)間 */
currentTime?: number
/** 結(jié)束時(shí)間 */
endTime?: number
/** 另一種方式,不傳當(dāng)前時(shí)間和結(jié)束時(shí)間,直接傳時(shí)間差 */
differTime?: number
}
interface ICbTime {
d: number
h: number
m: number
s: number
}
/**
* 倒計(jì)時(shí)hooks
* @param options 時(shí)間對(duì)象
* @param cb 倒計(jì)時(shí)完成時(shí)執(zhí)行的回調(diào)函數(shù)
* @param noImmediate 時(shí)間傳進(jìn)來(lái)滿足執(zhí)行回調(diào)條件時(shí),是否立即執(zhí)行回調(diào),默認(rèn)false執(zhí)行
*/
function useCountDown(
options: ITime,
cb?: () => void,
noImmediate?: boolean
): ICbTime {
const { currentTime = 0, endTime = 0, differTime = 0 } = options
const [diffTime, setDiffTime] = useState(0)
/** 組件接收到參數(shù)時(shí)的時(shí)間 */
const entryTime = useRef<number>(0)
/** 當(dāng)前倒計(jì)時(shí)要求的時(shí)間差 */
const maxTime = useRef<number>(0)
/** 是否可以執(zhí)行回調(diào) */
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報(bào)錯(cuò)問(wèn)題:
* 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
寫個(gè)demo看一下效果👇
const TimeArea = () => {
const { d, h, m, s } = useCountDown(
{
currentTime: 1631262176333,
endTime: 1831062176333
},
() => {
alert('倒計(jì)時(shí)結(jié)束')
}
)
return (
<div style={{ width: '200px', height: '200px' }}>
距離任務(wù)結(jié)束 vvxyksv9kd天<i>{h < 10 ? '0' + h : h}</i>:
<i>{m < 10 ? '0' + m : m}</i>:<i>{s < 10 ? '0' + s : s}</i>
</div>
)
}
到此這篇關(guān)于React+Typescript實(shí)現(xiàn)倒計(jì)時(shí)Hook的方法的文章就介紹到這了,更多相關(guān)React+Typescript實(shí)現(xiàn)倒計(jì)時(shí) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript變量中var,let和const的區(qū)別
這篇文章主要介紹了JavaScript變量中var,let和const的區(qū)別,JavaScript中一共有3種用來(lái)聲明變量的關(guān)鍵字,分別是var、let和const,文章通過(guò)圍繞主題展開對(duì)三個(gè)關(guān)鍵詞的詳細(xì)介紹,需要的朋友可以參考一下2022-09-09
webpack4從0搭建組件庫(kù)的實(shí)現(xiàn)
這篇文章主要介紹了webpack4從0搭建組件庫(kù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
js使用for循環(huán)與innerHTML獲取選中tr下td值
這篇文章主要與大家分享了js使用for循環(huán)與innerHTML獲取選中tr下td值的方法,很簡(jiǎn)單,但很實(shí)用,有需要的朋友可以參考下2014-09-09
js彈出層包含flash 不能關(guān)閉隱藏的2種處理方法
js彈出層包含flash 不能關(guān)閉隱藏的2種處理方法,需要的朋友可以參考一下2013-06-06
微信小程序?qū)崿F(xiàn)根據(jù)日期和時(shí)間排序功能
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)根據(jù)日期和時(shí)間排序功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
String.prototype實(shí)現(xiàn)的一些javascript函數(shù)介紹
這篇文章主要是對(duì)String.prototype實(shí)現(xiàn)的一些javascript函數(shù)進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-11-11
javascript中setTimeout和setInterval的unref()和ref()用法示例
本文通過(guò)一個(gè)小例子想大家講解了setTimeout和setInterval的unref()和ref()用法和使用環(huán)境,代碼很簡(jiǎn)潔,有需要的小伙伴自己參考下吧。2014-11-11
淺談如何使用webpack構(gòu)建多頁(yè)面應(yīng)用
這篇文章主要介紹了淺談如何使用webpack構(gòu)建多頁(yè)面應(yīng)用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05

