Question presented to candidate:
"We pass the current theme and the signed-in user through six layers of components, and most of those layers never use them. What are provide and inject, how would they fix this, and what would you watch out for?"
What a strong answer should cover:
provide(key, value)in an ancestor makes a value available to every descendant;inject(key)reads it, however deep, without the components in between knowing.- The nearest provider wins: a provider lower in the tree shadows the same key for its own subtree, which is how nested themes or forms work.
- Reactivity is not automatic: provide a ref, reactive object or computed to keep consumers in sync; a plain value is a one-time snapshot. Wrap with
readonly()and provide an update function so only the owner mutates. injecttakes a default (inject("locale", "en-GB")), or a factory with the third argumenttrue; with no provider and no default it returnsundefinedand warns.injectonly works synchronously insidesetup()(or<script setup>);app.providesupplies app-wide values, andapp.runWithContext()lets code outside components inject.- When to choose it over props (deep, subtree-scoped context) and over Pinia (app-global state), and using
Symbolkeys to avoid collisions.
Clarifying questions expected:
- "Is the theme global to the app, or can a section of the page override it?"
- "Who is allowed to change the user: any component, or only the auth layer?"
Code / implementation expected: Yes β a provider with a reactive value and an injecting descendant, ideally with a default and a readonly guard.