setContext / getContext Component Hierarchy Scopes
- Last updated
- Prerequisites:
- Svelte component tree structure
- Understanding of props vs shared state
- svelte
- context
- setContext
- getContext
- component-hierarchy
- di
Read at your depth
The practical view
setContext(key, value) stores a value for the current component; getContext(key) retrieves the nearest value set by an ancestor. Call them during component initialization: setContext('theme', theme); then in a descendant: const theme = getContext('theme');. The key can be a string, symbol, or object (often a Symbol or an object with an id to avoid collisions). Use context for: providing services/config to descendants without prop drilling, per-component-instance singletons, and library APIs (like SvelteKit's page store). Context is not reactive by itself — pass a $state value or store to share reactivity.
The same idea in other frameworks
React's Context.Provider/useContext is the analogue, though it's implemented via the fiber tree and re-renders consumers.Angular DI (providers + inject) provides the same hierarchy-scoped service sharing.Vue's provide()/inject() is the direct equivalent.Legacy vs modern
Prop drilling vs setContext/getContext
Threading the same value through many props couples components and bloats signatures; context shares it down the subtree without prop wiring.
<Grandparent theme={theme}><Parent theme={theme}><Child theme={theme} /></Parent></Grandparent> // ❌ OLDsetContext('theme', theme); // ✅ NEW: provide once
// deep descendant:
const theme = getContext('theme'); // ✅ NEW: read anywhere belowInterview gotchas
Context
This tests a common misconception — interviewers want to confirm you know setContext is a plain lookup, and that reactivity comes from the VALUE you store, not from context itself.
The mechanical answer
Context itself is non-reactive: setContext writes a value into a Map, and getContext returns whatever was stored — it does not track reads or re-deliver on change. If you set a primitive (setContext('theme', 'light')) and later change it, descendants that already called getContext keep the old value. To share reactive state, store a reactive container: a $state variable (setContext('theme', themeState)), a Svelte store, or a writable. Then descendants read the container and subscribe/react to its changes through the normal reactive mechanisms (reading the $state in templates/effects, or the store's $ syntax). The pattern 'context carries the reference, reactivity lives in the value' is the correct mental model.
Trap
The naive answer is 'setContext makes the value reactive'. It only shares the reference at init time. Another trap: calling setContext/getContext outside component initialization — getContext outside init throws, and calling setContext after the tree has read it has no retroactive effect. Candidates who explain the reference-carrying pattern show real understanding.
Context
This probes the scoping semantics — the nearest-ancestor lookup and per-subtree isolation that distinguish context from global singletons.
The mechanical answer
getContext starts at the current component instance and walks UP the component tree (parent, grandparent, ...), returning the first instance whose context map contains the key. So if a parent sets 'theme' and a grandparent also sets 'theme', the child gets the parent's value — nearest ancestor wins. This per-tree resolution means two sibling subtrees can each provide different values for the same key without conflict. Contrast with a module-level singleton (an exported variable), which is shared globally across the whole app — no scoping, no per-subtree variation, and it cannot be provided differently per instance. Context is the hierarchical, instance-scoped alternative, which is why component libraries use it for per-component configuration.
Trap
The naive answer is 'context is like a global store'. It is scoped to the component subtree and resolved nearest-first. Another trap: assuming keys must be unique strings — string keys can collide across libraries, so Symbol or object keys are recommended to avoid accidental collisions. Candidates who describe the ancestor walk and the collision-avoidance keying show real depth.