All files / src/shared/hooks useDebouncedCallback.hook.ts

100% Statements 27/27
100% Branches 7/7
100% Functions 1/1
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 411x   1x               1x 1x 43x 43x   43x 43x   43x   43x 21x 21x 9x 9x 21x 43x   43x 43x 11x 2x 2x 11x 7x 11x 11x 43x   43x  
import { useCallback, useEffect, useRef } from 'react';
 
/**
 * Returns a debounced version of the provided callback.
 * The callback will only execute after `delay` ms of inactivity.
 * Automatically cleans up pending timers on unmount.
 * @param callback - The function to debounce
 * @param delay - Debounce delay in milliseconds
 * @returns A debounced version of the callback with the same signature
 * @source
 */
export function useDebouncedCallback<T extends (...args: never[]) => void>(
  callback: T,
  delay: number,
): (...args: Parameters<T>) => void {
  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const callbackRef = useRef(callback);
 
  callbackRef.current = callback;
 
  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);
 
  return useCallback(
    (...args: Parameters<T>) => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
      timeoutRef.current = setTimeout(() => {
        callbackRef.current(...args);
      }, delay);
    },
    [delay],
  );
}