1. 程式人生 > 其它 >react實現自定義hooks(倒計時)

react實現自定義hooks(倒計時)

實現思路

setTimeout + 遞迴,然後就是一個時間的轉化。
特別要注意在特定的地方清除定時器

線上預覽

react倒計時hooks

核心程式碼

import { useRef, useState, useEffect } from "react";

const formatMoment = (ms, type = "DD HH:mm:ss") => {
  if (ms <= 0)
    return {
      day: 0,
      hour: 0,
      minute: 0,
      second: 0
    };
  let remainTs = ms;
  let day = 0;
  if (type.indexOf("DD") !== -1) {
    day = Math.floor(ms / 1000 / 3600 / 24);
    remainTs = ms % (24 * 60 * 60 * 1000);
  }
  const hour = Math.floor(remainTs / 60 / 60 / 1000);
  remainTs %= 60 * 60 * 1000;
  const minute = Math.floor(remainTs / 60 / 1000);
  remainTs %= 60 * 1000;
  const second = Math.floor(remainTs / 1000);

  return {
    day,
    hour,
    minute,
    second
  };
};
/**
 * timeRemaining:剩餘時間的時間戳
 * onComplete:倒計時結束的回撥
 */
export default function useCountdown(timeRemaining, onComplete) {
  const cancelToken = useRef(false);
  const timer = useRef();
  const [countDownTime, setCountDownTime] = useState(0);
  useEffect(
    () => () => {
      cancelToken.current = true;
    },
    []
  );

  useEffect(() => {
    count(timeRemaining);

    return () => {
      window.clearTimeout(timer.current);
    };
  }, [timeRemaining]);

  const count = (remainTs) => {
    if (timer.current) window.clearTimeout(timer.current);
    if (cancelToken.current) return;
    if (remainTs <= 0 && Number(timeRemaining) > 0) {
      window.clearTimeout(timer.current);
      onComplete();
    } else {
      setCountDownTime(remainTs - 1000);
      timer.current = window.setTimeout(() => count(remainTs - 1000), 1000);
    }
  };
  const { day, hour, minute, second } = formatMoment(countDownTime);
  return { day, hour, minute, second };
}