This error occurs when a React Context Consumer is rendered in a component tree that is not wrapped by the corresponding Context Provider. Context values are undefined or use default values when accessed outside their Provider scope.
React Context provides a way to share values between components without explicitly passing props through every level of the component tree. The Context API consists of two parts: a Provider component that supplies the value, and Consumer components (or useContext hooks) that read it. When you use Context.Consumer or useContext() to access a context value, React looks up the component tree to find the nearest matching Provider. If no Provider is found, React will either return the default value passed to createContext(), or undefined if no default was provided. This error message indicates that your code is attempting to consume a context value in a component that is not a descendant of the corresponding Provider. This means the Consumer cannot access the intended context value and will behave unexpectedly, potentially breaking your application logic.
Check that your Context.Provider is placed high enough in the component tree to wrap all components that need to consume the context.
Incorrect structure:
import { createContext } from 'react';
const ThemeContext = createContext();
function App() {
return (
<div>
<Navbar /> {/* Cannot access ThemeContext */}
<ThemeContext.Provider value="dark">
<Content />
</ThemeContext.Provider>
</div>
);
}Correct structure:
function App() {
return (
<ThemeContext.Provider value="dark">
<div>
<Navbar /> {/* Can now access ThemeContext */}
<Content />
</div>
</ThemeContext.Provider>
);
}Modern React code should use the useContext hook instead of Context.Consumer. This makes the code cleaner and provides better error messages.
Old Consumer pattern:
function MyComponent() {
return (
<ThemeContext.Consumer>
{value => <div>Theme: {value}</div>}
</ThemeContext.Consumer>
);
}Modern useContext pattern:
import { useContext } from 'react';
function MyComponent() {
const theme = useContext(ThemeContext);
return <div>Theme: {theme}</div>;
}Build a custom hook that validates the context is being used within a Provider. This provides clear error messages during development.
import { createContext, useContext } from 'react';
const ThemeContext = createContext(undefined);
export function useTheme() {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('dark');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}Now when you use useTheme() outside a Provider, you get a clear error message pointing to the problem.
If you're using npm link, monorepos, or have duplicate React installations, you may have multiple Context instances that don't match.
Check for duplicate React:
npm ls react
# or
yarn why reactIn a monorepo, ensure React is hoisted:
// package.json (workspace root)
{
"workspaces": {
"nohoist": []
}
}For linked packages, use peerDependencies:
// your-library/package.json
{
"peerDependencies": {
"react": "^18.0.0"
}
}If you're still using Context.Consumer, ensure you're passing a render function as the only child.
Incorrect - multiple children:
<ThemeContext.Consumer>
<div>Theme: {value}</div> {/* Wrong! */}
</ThemeContext.Consumer>Incorrect - not a function:
<ThemeContext.Consumer>
<div>Theme</div> {/* Wrong! */}
</ThemeContext.Consumer>Correct - single render function:
<ThemeContext.Consumer>
{value => <div>Theme: {value}</div>}
</ThemeContext.Consumer>For application-wide context (theme, auth, etc.), place the Provider in your root component or layout.
Next.js App Router:
// app/layout.tsx
import { ThemeProvider } from '@/contexts/ThemeContext';
export default function RootLayout({ children }) {
return (
<html>
<body>
<ThemeProvider>
{children}
</ThemeProvider>
</body>
</html>
);
}Create React App:
// src/index.js
import { ThemeProvider } from './contexts/ThemeContext';
root.render(
<React.StrictMode>
<ThemeProvider>
<App />
</ThemeProvider>
</React.StrictMode>
);Context Default Values vs. Undefined:
When creating a context, you can provide a default value:
const ThemeContext = createContext('light'); // with default
const AuthContext = createContext(undefined); // no defaultIf you provide a default value, consuming the context outside a Provider will return that default instead of throwing an error. This can hide bugs. It's often better to use undefined as the default and validate in a custom hook.
Performance Considerations:
Every time the Provider's value changes, all consumers re-render. To prevent unnecessary re-renders:
const [theme, setTheme] = useState('dark');
// ❌ Creates new object every render
<ThemeContext.Provider value={{ theme, setTheme }}>
// ✅ Memoize the value object
const value = useMemo(() => ({ theme, setTheme }), [theme]);
<ThemeContext.Provider value={value}>Testing Components with Context:
When testing components that use context, wrap them in the Provider:
import { render } from '@testing-library/react';
import { ThemeProvider } from './contexts/ThemeContext';
test('renders with theme', () => {
render(
<ThemeProvider>
<MyComponent />
</ThemeProvider>
);
});Server-Side Rendering Considerations:
In Next.js with Server Components, context only works in Client Components. Mark your Provider with "use client":
'use client';
import { createContext, useState } from 'react';
export const ThemeContext = createContext(undefined);
export function ThemeProvider({ children }) {
// Provider implementation
}React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite