UNPKG

ahooks

Version:
53 lines (52 loc) 1.93 kB
import dayjs from 'dayjs'; import { useEffect, useMemo, useState } from 'react'; import useLatest from '../useLatest'; import { isNumber } from '../utils'; const calcLeft = (target) => { if (!target) { return 0; } // https://stackoverflow.com/questions/4310953/invalid-date-in-safari const left = dayjs(target).valueOf() - Date.now(); return left < 0 ? 0 : left; }; const parseMs = (milliseconds) => { return { days: Math.floor(milliseconds / 86400000), hours: Math.floor(milliseconds / 3600000) % 24, minutes: Math.floor(milliseconds / 60000) % 60, seconds: Math.floor(milliseconds / 1000) % 60, milliseconds: Math.floor(milliseconds) % 1000, }; }; const useCountdown = (options = {}) => { const { leftTime, targetDate, interval = 1000, onEnd } = options || {}; const memoLeftTime = useMemo(() => { return isNumber(leftTime) && leftTime > 0 ? Date.now() + leftTime : undefined; }, [leftTime]); const target = 'leftTime' in options ? memoLeftTime : targetDate; const [timeLeft, setTimeLeft] = useState(() => calcLeft(target)); const onEndRef = useLatest(onEnd); useEffect(() => { if (!target) { // for stop setTimeLeft(0); return; } // 立即执行一次 setTimeLeft(calcLeft(target)); const timer = setInterval(() => { var _a; const targetLeft = calcLeft(target); setTimeLeft(targetLeft); if (targetLeft === 0) { clearInterval(timer); (_a = onEndRef.current) === null || _a === void 0 ? void 0 : _a.call(onEndRef); } }, interval); return () => clearInterval(timer); }, [target, interval]); const formattedRes = useMemo(() => parseMs(timeLeft), [timeLeft]); return [timeLeft, formattedRes]; }; export default useCountdown;