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