1. import { useRef, useEffect, useCallback } from 'react';
    2. export interface Opts {
    3. immediate?: boolean;
    4. manual?: boolean;
    5. }
    6. export interface IntervalActions {
    7. start: () => Promise<void>;
    8. stop: () => Promise<void>;
    9. }
    10. const loop = async () => {};
    11. const useInterval = (fn: () => void, delay: number, opts?: Opts) => {
    12. const timerRef = useRef<number | null>(null);
    13. const fnRef = useRef<() => void>();
    14. const ref = useRef<IntervalActions>({ start: loop, stop: loop });
    15. fnRef.current = fn;
    16. const stop = useCallback(async () => {
    17. if (timerRef.current) {
    18. clearInterval(timerRef.current);
    19. timerRef.current = null;
    20. }
    21. }, [timerRef]);
    22. /** 开始 */
    23. const start = useCallback(async () => {
    24. stop?.();
    25. timerRef.current = window.setInterval(() => {
    26. fnRef.current?.();
    27. }, delay);
    28. }, [delay]);
    29. useEffect(() => {
    30. const hasBack = delay === undefined || delay === null;
    31. if (hasBack) {
    32. ref.current = { start: loop, stop: loop };
    33. } else {
    34. ref.current = { start, stop };
    35. }
    36. if (opts?.immediate) {
    37. fnRef.current?.();
    38. }
    39. if (!opts?.manual && !hasBack) {
    40. ref.current.start();
    41. }
    42. return () => {
    43. ref.current.stop();
    44. };
    45. }, [delay]);
    46. return { ...ref.current };
    47. };
    48. export default useInterval;

    https://zhuanlan.zhihu.com/p/141673983