1. import { useRef, useEffect, useCallback } from 'react';
    2. import { loop } from "../utils/fn";
    3. export interface Opts {
    4. manual?: boolean;
    5. }
    6. const initialState = { start: loop, stop: loop };
    7. const useTimeout = (fn: () => void, delay: undefined | null | number, opts?: Opts) => {
    8. const timerRef = useRef<number>(null);
    9. const fnRef = useRef<() => void>();
    10. const ref = useRef<{ start: () => void; stop: () => void }>(initialState);
    11. fnRef.current = fn;
    12. const stop = useCallback(() => {
    13. if (timerRef.current) {
    14. clearTimeout(timerRef.current);
    15. timerRef.current = null;
    16. }
    17. }, [timerRef]);
    18. const start = useCallback(() => {
    19. stop();
    20. timerRef.current = setTimeout(() => {
    21. fnRef.current?.();
    22. }, delay);
    23. }, [timerRef, delay]);
    24. useEffect(() => {
    25. const hasBack = delay === undefined || delay === null;
    26. ref.current = hasBack ? initialState : { start, stop };
    27. if (!opts?.manual) {
    28. ref.current.start();
    29. }
    30. return ref.current.stop;
    31. }, [delay]);
    32. return { ...ref.current } as const;
    33. };
    34. export default useTimeout;