import { useLayoutEffect, useMemo, useRef } from "react"; function debounce any>( func: T, timeout: number, executeFirstCall: boolean = false, ): (...args: Parameters) => ReturnType | undefined { let timer: ReturnType | null = null; let result: ReturnType | undefined; return (...args: Parameters): ReturnType | undefined => { const callNow = executeFirstCall && !timer; if (timer) { clearTimeout(timer); } timer = setTimeout(() => { timer = null; result = func(...args); }, timeout); if (callNow) { result = func(...args); } return result; }; } export function useDebounce any>( callback: T, delay: number = 600, executeFirstCall: boolean = true, ): (...args: Parameters) => ReturnType | undefined { const callbackRef = useRef(callback); useLayoutEffect(() => { callbackRef.current = callback; }, [callback]); return useMemo( () => debounce( (...args: Parameters) => callbackRef.current(...args), delay, executeFirstCall, ), [delay, executeFirstCall], ); }