import { useMemo, useState } from "react"; const debounce = (fn: (...args: T[]) => void, delay: number) => { let timeout: NodeJS.Timeout | undefined; return (...args: T[]) => { if (timeout !== undefined) { clearTimeout(timeout); } timeout = setTimeout(fn, delay, ...args); }; }; export function useStateDebounced(initialValue: T, delay: number) { const [, _setInputValue] = useState(initialValue); const [debouncedInputValue, setDebouncedInputValue] = useState( initialValue ); const memoizedDebounce = useMemo( () => debounce((value: T) => { setDebouncedInputValue(value); }, delay), [delay] ); const setInputValue = (value: T | ((prevState: T) => T)) => { if (value instanceof Function) { _setInputValue((p) => { const mutated = value(p); memoizedDebounce(mutated); return mutated; }); } else { _setInputValue(value); memoizedDebounce(value); } }; return [debouncedInputValue, setInputValue] as const; }