export const useCountDown = (countDownTimeStamp: number) => {
const [second, setSecond] = useState(0);
const interval = 1000;
const countRef = useRef(0);
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(0);
const startTimeRef = useRef(0);
const countTask = useCallback(() => {
countRef.current += 1;
const offset = +new Date() - (startTimeRef.current + interval * countRef.current);
let nextTime = interval - offset;
nextTime <= 0 && (nextTime = 0);
setSecond(pre => {
const resuide = pre - 1;
if (resuide <= 0) {
timerRef.current && clearTimeout(timerRef.current);
return 0;
} else {
setTimeout(countTask, nextTime);
return resuide;
}
});
}, []);
useEffect(() => {
startTimeRef.current = new Date().getTime();
setSecond(countDownTimeStamp);
const timer = timerRef.current;
setTimeout(countTask, interval);
return () => {
if (timer) {
clearTimeout(timer);
timerRef.current = null;
}
};
}, [countDownTimeStamp, countTask]);
return { second };
};