import { useEffect, useState } from "react"; import { debounce } from "../utils/debounce"; /** * Returns a debounced copy of `value` that only updates after `value` has * stopped changing for `delayMs`. Use it to keep a controlled input * responsive (bind the input to the raw value) while throttling the * expensive work it drives — a network query, a react-query cache key, a * filter over a large list. * * The pending update is cancelled on unmount and whenever `value` changes * again, so a fast typer never fires an update per keystroke and there is no * setState-after-unmount on the trailing edge. * * @example * const [term, setTerm] = useState(""); * const debouncedTerm = useDebouncedValue(term, 300); * // — instant feedback * // useQuery({ queryKey: ["search", debouncedTerm], ... }) — one fetch per pause */ export function useDebouncedValue(value: T, delayMs = 300): T { const [debounced, setDebounced] = useState(value); useEffect(() => { const update = debounce((next: T) => setDebounced(next), delayMs); update(value); return update.cancel; }, [value, delayMs]); return debounced; }