tezvyn:

How would you implement a custom useDebounce hook using useState and useEffect?

AI-drafted, machine-checkedSource: telerik.comintermediate
How would you implement a custom useDebounce hook using useState and useEffect?

It tests effect cleanup and stale closure awareness. Use useState for the debounced value, useEffect to set a setTimeout when the input changes, and return a cleanup calling clearTimeout. Omitting cleanup leaks timers and fires stale values.

WHAT THIS TESTS: This question tests your understanding of React effect lifecycles, cleanup semantics, and how to avoid stale closures when managing asynchronous timers. Interviewers want to see that you know useEffect is not just for starting side effects but also for cancelling them when dependencies change or the component unmounts.

A GOOD ANSWER COVERS: First, initialize a piece of state with useState to hold the debounced value, usually starting with the initial input value. Second, inside useEffect, create a timer with setTimeout that waits for the specified delay in milliseconds before calling setDebouncedValue with the latest input. Third, return a cleanup function from useEffect that calls clearTimeout using the timer ID; this cancels the previous timer whenever the input value or delay changes, preventing overlapping updates. Fourth, include both the raw value and the delay in the effect dependency array so the timer resets if either changes. Fifth, return the debounced state from the hook so components can read it directly.

COMMON WRONG ANSWERS: A major red flag is forgetting the cleanup function entirely; without clearTimeout, every keystroke spawns a new timer and all of them fire, defeating the purpose of debounce. Another mistake is omitting the delay from the dependency array, which can lead to stale closures where a 500 ms delay feels like 200 ms because the effect captured an old variable. Some candidates also try to manage the timer with useRef to avoid re-renders, which is unnecessary for a standard debounce and adds complexity without benefit. Returning the setter instead of the value is also incorrect because the hook should encapsulate the timing logic.

LIKELY FOLLOW-UPS: The interviewer might ask how you would handle a changing delay prop mid-flight, or how to add a leading-edge option so the first change fires immediately. They may also ask how to unit test the hook with React Testing Library, or how to convert it to a useMemo-based implementation if the delay is zero.

ONE CONCRETE EXAMPLE: Imagine a search input that calls an API. The user types React quickly. Without debounce, the component sends six requests. With a 300 ms delay, the effect starts a 300 ms timer on every keystroke but cancels the previous one. Only when the user pauses for 300 ms does setDebouncedValue run, triggering a single fetch.

Source: telerik.com

Read the original → telerik.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.