Build a hook that returns a debounced copy of a value. Debouncing means waiting for activity to settle before reacting: as a value changes rapidly, you ignore every intermediate update and only commit once the changes have stopped for a moment. The classic case is a search box — the user types r, re, rea, reac, react, but you only want to fire one search, for react, after they pause. useDebounce(value, delay) gives you that settled value: it mirrors the latest value, but only updates after delay milliseconds have passed with no further changes.
function useDebounce<T>(value: T, delay: number): T;
The returned value tracks value but lags behind it, updating only after delay ms of quiet.
function Search() {
const [text, setText] = useState('');
const debounced = useDebounce(text, 300);
// Fires only after the user stops typing for 300ms.
useEffect(() => {
if (debounced) fetchResults(debounced);
}, [debounced]);
return <input value={text} onChange={(e) => setText(e.target.value)} />;
}
// A burst of changes collapses into a single, final update:
// value: 'r' 're' 'rea' 'reac' 'react' (then a pause)
// debounced: '' '' '' '' '' → 'react'
// Only the LAST value is ever committed; the intermediates are skipped.
value right away — no delay on mount.value changes several times faster than delay, the debounced value must skip every intermediate and commit only the final one, once the changes stop.value restarts the quiet period from zero; the hook commits only after delay ms with no further change.'', 0, or false must commit like any other — "no change yet" and "changed to something falsy" are different.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.