We use cookies for site analytics. Accept to help us understand how the site is used. See our Privacy Policy for details.
A medium frontend problem, graded against 5 test cases (3 of them hidden).
React and browser-platform problems - hooks, event handling, and rendering behaviour.
Reach for it when you see: A component, hook, or DOM-behaviour question rather than an algorithm.
More Frontendproblems →```tsx
export function useDebounce<T>(value: T, delay: number): T {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const handle = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(handle);
}, [value, delay]);
return debounced;
}
```
Why this works: every change to `value` schedules a new timeout AND cancels the previous one (in the cleanup). Only the last value before a quiet period of `delay` ms survives to be set into `debounced`. The trailing-edge model.
Variants worth knowing:
- Leading edge: fire immediately, then ignore for `delay` ms. Useful for "submit" buttons (prevent double-clicks).
- Both edges: fire immediately AND on the trailing edge.
- maxWait: force a flush after `maxWait` ms even if events keep coming - prevents indefinite starvation. Lodash `debounce` supports all of these.
Throttle vs debounce: throttle limits to N calls per second (drop excess); debounce waits for silence before firing. Pick based on UX: scroll handlers want throttle, search inputs want debounce.
The full reference solution in every supported language stays in the editor above - reveal it there once you have had a real attempt.
Read off this problem's own test suite, so these are the cases a submission actually has to survive.
These apply to the pattern as a whole, not just this problem.