Question presented to candidate:
"A search box re-renders an expensive result list on every keystroke. Would you debounce it or use useDeferredValue, and what is the actual difference?"
What a strong answer should cover:
useDeferredValuereturns a lagging copy of a value. The component renders twice per change: once with the new value and the old deferred one, then again once React catches up.- Debouncing delays the state update itself. Values in the middle of a burst are never processed at all.
- So the trade is: deferring processes every value, late; debouncing processes fewer values, later.
- Deferring is interruptible and adaptive — it yields to urgent work and keeps up on a fast machine — where a debounce is a fixed timer that is wrong on both fast and slow devices.
- With a debounce the UI shows stale content for the whole delay, including after the user has stopped typing.
useDeferredValueneeds the expensive child to be memoised, or it re-renders anyway and the deferral buys nothing.- Debouncing is still correct for things with a cost per call — network requests, analytics, autosave. Deferring is for render cost.
Clarifying questions expected:
- "Is the expensive part rendering, or a network request?" — that alone decides which tool.
- "Is the result list already memoised?"
Code / implementation expected: Optional. A one-line useDeferredValue plus a memo wrapper is enough to show the shape.