溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用React+Typescript實現(xiàn)倒計時的功能

發(fā)布時間:2021-09-14 11:33:35 來源:億速云 閱讀:195 作者:chen 欄目:開發(fā)技術

這篇文章主要介紹“怎么用React+Typescript實現(xiàn)倒計時的功能”,在日常操作中,相信很多人在怎么用React+Typescript實現(xiàn)倒計時的功能問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么用React+Typescript實現(xiàn)倒計時的功能”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

import { useEffect, useRef } from 'react'

/**
 * interTerval hooks組件
 * @param fn 執(zhí)行函數(shù)
 * @param delay 時間
 * @param options immediate為true時,先立即執(zhí)行一次fn函數(shù)后再執(zhí)行定時器
 */
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

實現(xiàn)倒計時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 倒計時完成時執(zhí)行的回調函數(shù)
 * @param noImmediate 時間傳進來滿足執(zhí)行回調條件時,是否立即執(zhí)行回調,默認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ù)時的時間 */
  const entryTime = useRef<number>(0)
  /** 當前倒計時要求的時間差 */
  const maxTime = useRef<number>(0)
  /** 是否可以執(zhí)行回調 */
  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' }}>
        距離任務結束 4vv49wn天<i>{h < 10 ? '0' + h : h}</i>:
        <i>{m < 10 ? '0' + m : m}</i>:<i>{s < 10 ? '0' + s : s}</i>
      </div>
    )
  }

到此,關于“怎么用React+Typescript實現(xiàn)倒計時的功能”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI