React Context value is always the default — Consumer rendered outside its Provider
A component calling useContext (or rendering a Context.Consumer) only sees the value from the nearest matching Provider above it in the tree. If that component is rendered outside any Provider — or under the wrong instance of one, in an app with multiple providers for the same context — it silently falls back to the default value passed to createContext(), with no error thrown.
What causes this error
Context lookups walk up the tree to find the nearest enclosing Provider for that specific context object. Unlike most React mistakes, this one doesn't throw — a component outside any provider, or one rendered via a portal/route that bypasses the provider tree, just silently receives whatever default value was passed to createContext(defaultValue), which is easy to mistake for a real (but wrong) value.
The Fix
const ThemeContext = createContext('light'); // default fallback
// Wrong — ThemedButton rendered outside any ThemeContext.Provider
function App() {
return <ThemedButton />; // always gets 'light', the default
}
// Fix — wrap the consuming component in the actual Provider
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}To catch this earlier, set the `createContext` default to something obviously wrong during development (like `undefined`) and throw inside your custom hook if it's ever received, instead of a plausible-looking default.
Common causes / variations
- Rendering a component via `createPortal` outside the DOM subtree the Provider covers (though context still crosses portals in the React tree — the DOM location doesn't matter, but a genuinely separate render root does)
- Multiple `Provider`s for the same context with different values, and the component landing under the wrong one
- Forgetting the `Provider` entirely after refactoring where a context is defined vs. where it's used
Related errors
See also: Invalid hook call, cache() called outside a request.
Comments
Loading comments...