Build a React hook that returns a throttled copy of a value. As the source value changes — on every keystroke, scroll event, or window resize — the throttled copy updates at most once per interval milliseconds, so anything reading it (an expensive search, a chart redraw) runs on a steady cadence instead of on every change. Throttle is the close cousin of debounce, but they answer different questions: debounce waits for the source to go quiet before committing, while throttle commits on a fixed clock no matter how busy the source is. The catch most people miss: the very last value of a burst must still land, even though it arrived before the interval elapsed.
function useThrottle<T>(value: T, interval: number): T;
The hook returns the throttled value. The first render returns value as-is.
function Search({ query }) {
// `query` may change on every keystroke; `throttled` changes at most
// once every 200ms, so we only re-run the expensive search on a cadence.
const throttled = useThrottle(query, 200);
const results = useMemo(() => expensiveSearch(throttled), [throttled]);
return <ResultList items={results} />;
}
// interval = 200, source changes at t = 0, 50, 90, 130 with values a,b,c,d
// t=0: throttled === 'a' (first value lands immediately)
// t=50: throttled === 'a' (inside the interval — held)
// t=90: throttled === 'a' (still inside — held)
// t=130: throttled === 'a' (still inside — held)
// t=200: throttled === 'd' (interval elapsed — the LATEST value lands)
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.