Question presented to candidate: "A value from the top of your app is needed six levels down. What are your options?"
What a strong answer should cover:
- Prop drilling is passing a prop through components that do not use it, purely to reach a descendant.
- It is not automatically wrong — two levels is explicit and readable. It becomes a problem past three or four, when intermediate components take props solely to forward them.
- The real costs: you can no longer see which components actually depend on a value; renaming means touching every level; and the intermediate components have a wider interface than their job needs.
- The escape ladder, in order: composition (
childrenor element slots), then Context, then a store. - Composition first is the point most candidates miss — restructuring so the deep component is created higher up removes the threading entirely, needs no new machinery, and has a measurable re-render benefit.
- Context is a transport, not a state manager; every consumer re-renders when the value changes.
- A store (Redux, Zustand, Jotai) adds selector subscriptions, so only components reading the changed slice re-render.
- Custom hooks can hide the
useContextcall so consumers do not import the context directly.
Clarifying questions expected:
- "How many levels, and do any of the intermediate components use the value?"
- "How often does it change, and how many components read it?" — that decides Context versus a store.
Code / implementation expected: Yes — the drilled version and the composition refactor side by side.