import { useRef, useEffect, useCallback } from 'react';export interface Opts { immediate?: boolean; manual?: boolean;}export interface IntervalActions { start: () => Promise<void>; stop: () => Promise<void>;}const loop = async () => {};const useInterval = (fn: () => void, delay: number, opts?: Opts) => { const timerRef = useRef<number | null>(null); const fnRef = useRef<() => void>(); const ref = useRef<IntervalActions>({ start: loop, stop: loop }); fnRef.current = fn; const stop = useCallback(async () => { if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; } }, [timerRef]); /** 开始 */ const start = useCallback(async () => { stop?.(); timerRef.current = window.setInterval(() => { fnRef.current?.(); }, delay); }, [delay]); useEffect(() => { const hasBack = delay === undefined || delay === null; if (hasBack) { ref.current = { start: loop, stop: loop }; } else { ref.current = { start, stop }; } if (opts?.immediate) { fnRef.current?.(); } if (!opts?.manual && !hasBack) { ref.current.start(); } return () => { ref.current.stop(); }; }, [delay]); return { ...ref.current };};export default useInterval;
https://zhuanlan.zhihu.com/p/141673983