import { useCallback, useEffect, useRef } from "react"; /** * Custom hook for debouncing function calls * * @param callback - Function to debounce * @param delay - Delay in milliseconds before invoking the callback * @returns Debounced version of the callback function * * @example * ```tsx * const debouncedSearch = useDebounce((query: string) => { * performSearch(query); * }, 300); * * // Call multiple times, only last call executes after 300ms * debouncedSearch("hello"); * ``` */ export function useDebounce void>(callback: T, delay: number): (...args: Parameters) => void { const timeoutRef = useRef | null>(null); const callbackRef = useRef(callback); // Keep callback ref up to date useEffect(() => { callbackRef.current = callback; }, [callback]); // Clean up timeout on unmount useEffect(() => { return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } }; }, []); return useCallback( (...args: Parameters) => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(() => { callbackRef.current(...args); }, delay); }, [delay], ); }