Question presented to candidate: "What is the dependency array actually for, and why do people get it wrong so often?"
What a strong answer should cover:
- It declares which reactive values the hook depends on. React compares them with
Object.isand only re-runs (or re-creates) when one changed. - Three cases: omitted (runs every render),
[](once on mount),[a, b](whenaorbchange). - The comparison is by identity, not by value. Two structurally identical objects are different dependencies.
- That is why an inline object, array, or function in deps re-runs the hook on every render — the classic infinite-loop bug when the effect also sets state.
- The fix hierarchy: depend on primitives where possible; otherwise stabilise with
useMemo/useCallback; or move the value inside the effect. - Do not lie to the linter. An omitted dependency means the hook closes over a stale value — the cause of most stale-closure bugs.
useCallbackanduseMemouse the same array for the same reason: to decide whether to return the cached value or make a new one.useEffectEventas the modern answer for logic that should read the latest value without being reactive.
Clarifying questions expected:
- "Is the dependency a primitive or an object?" — it changes the whole answer.
- "Is the effect setting state that feeds back into its own dependencies?"
Code / implementation expected: Yes — the object-literal-in-deps bug and its fix.