This error occurs when a component tries to consume a React Context using useContext() or Context.Consumer, but is rendered outside the corresponding Context.Provider component tree. Context values are undefined or use their default values when accessed outside a provider.
React's Context API allows you to share data across component trees without prop drilling. When you create a context with createContext(), you get both a Provider and a Consumer. The Provider component wraps the part of your component tree that needs access to the context value. This error happens when you call useContext() or use Context.Consumer in a component that is not wrapped by the corresponding Context.Provider. React will not throw an error in most cases—instead, it will return the default value passed to createContext(). However, if no meaningful default was provided or the default is undefined, your component will try to use undefined context values, leading to bugs or crashes. The core issue is a mismatch in the component tree structure: the consuming component needs to be a descendant (child, grandchild, etc.) of the Provider component. If the Provider is missing, in a different subtree, or rendered after the consumer, React cannot supply the context value.
Check your component tree to ensure the Provider wraps all components that need access to the context. The consuming component must be a descendant of the Provider.
Correct structure:
// App.jsx
import { createContext, useContext } from 'react';
const UserContext = createContext(undefined);
function UserProvider({ children }) {
const user = { name: 'John', email: '[email protected]' };
return (
<UserContext.Provider value={user}>
{children}
</UserContext.Provider>
);
}
function UserProfile() {
const user = useContext(UserContext); // ✅ Works - wrapped by Provider
return <div>{user.name}</div>;
}
function App() {
return (
<UserProvider>
<UserProfile />
</UserProvider>
);
}Incorrect structure (consumer outside Provider):
function App() {
return (
<div>
<UserProfile /> {/* ❌ Not wrapped by Provider */}
<UserProvider>
<OtherComponent />
</UserProvider>
</div>
);
}Instead of using useContext() directly, create a custom hook that validates the context value and provides a clear error message when the Provider is missing.
// contexts/UserContext.jsx
import { createContext, useContext } from 'react';
const UserContext = createContext(undefined);
export function UserProvider({ children }) {
const user = { name: 'John', email: '[email protected]' };
return (
<UserContext.Provider value={user}>
{children}
</UserContext.Provider>
);
}
// Custom hook with error checking
export function useUser() {
const context = useContext(UserContext);
if (context === undefined) {
throw new Error('useUser must be used within a UserProvider');
}
return context;
}Now use the custom hook instead of useContext() directly:
// UserProfile.jsx
import { useUser } from './contexts/UserContext';
function UserProfile() {
const user = useUser(); // Clear error if Provider is missing
return <div>{user.name}</div>;
}If you're getting context errors, move the Provider to a higher level in your app, typically near the root. This ensures all child components can access the context.
For Next.js App Router:
// app/layout.tsx
import { UserProvider } from '@/contexts/UserContext';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<UserProvider>
{children}
</UserProvider>
</body>
</html>
);
}For standard React app:
// main.jsx or index.jsx
import { UserProvider } from './contexts/UserContext';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<UserProvider>
<App />
</UserProvider>
</React.StrictMode>
);A common mistake is using the Context object itself as a component instead of Context.Provider.
Incorrect (typo):
import { UserContext } from './contexts/UserContext';
function App() {
return (
<UserContext value={user}> {/* ❌ Wrong - this is the Context object, not the Provider */}
<UserProfile />
</UserContext>
);
}Correct:
import { UserContext } from './contexts/UserContext';
function App() {
return (
<UserContext.Provider value={user}> {/* ✅ Correct - using Provider */}
<UserProfile />
</UserContext.Provider>
);
}If you want components to work without a Provider (for testing or isolated usage), provide a meaningful default value to createContext().
// With no default (common pattern)
const UserContext = createContext(undefined);
// Result: useContext returns undefined when no Provider
// With default value
const UserContext = createContext({
name: 'Guest',
email: '[email protected]',
isAuthenticated: false,
});
// Result: useContext returns this object when no Provider
// With null (explicit no-value)
const UserContext = createContext(null);
// Result: useContext returns null when no ProviderHowever, most of the time you want to enforce Provider usage with a custom hook that throws an error (see Step 2).
If your Provider is rendered conditionally, ensure consuming components are also inside that conditional, or restructure to keep the Provider always mounted.
Problem:
function App() {
const [showProvider, setShowProvider] = useState(true);
return (
<div>
{showProvider && (
<UserProvider>
<Dashboard />
</UserProvider>
)}
<UserProfile /> {/* ❌ Outside Provider when showProvider is true */}
</div>
);
}Solution 1 - Move consumer inside:
function App() {
const [showProvider, setShowProvider] = useState(true);
return (
<div>
{showProvider && (
<UserProvider>
<Dashboard />
<UserProfile /> {/* ✅ Inside Provider */}
</UserProvider>
)}
</div>
);
}Solution 2 - Keep Provider always mounted:
function App() {
return (
<UserProvider>
<Dashboard />
<UserProfile />
</UserProvider>
);
}Multiple Contexts:
When using multiple contexts, ensure each has its own Provider and consumers are wrapped by all necessary Providers. You can nest Providers or use a component to combine them:
function AllProviders({ children }) {
return (
<UserProvider>
<ThemeProvider>
<LanguageProvider>
{children}
</LanguageProvider>
</ThemeProvider>
</UserProvider>
);
}TypeScript Best Practices:
Create contexts with undefined as the default and type the custom hook's return value as non-undefined:
type UserContextType = { name: string; email: string };
const UserContext = createContext<UserContextType | undefined>(undefined);
export function useUser(): UserContextType {
const context = useContext(UserContext);
if (context === undefined) {
throw new Error('useUser must be used within a UserProvider');
}
return context; // TypeScript knows this is UserContextType (not undefined)
}Testing:
When testing components that use context, wrap them with the Provider in your test setup:
import { render } from '@testing-library/react';
import { UserProvider } from './contexts/UserContext';
test('renders user profile', () => {
render(
<UserProvider>
<UserProfile />
</UserProvider>
);
// assertions...
});Default Value Behavior:
The default value passed to createContext() is ONLY used when there is NO Provider component above the consumer in the tree. If a Provider exists but passes undefined as the value, consumers will receive undefined, not the default value. To handle this, always validate the context value in your custom hook.
Performance Consideration:
Every time the Provider's value prop changes, all consuming components re-render. To optimize, memoize the context value with useMemo():
function UserProvider({ children }) {
const [user, setUser] = useState({ name: 'John' });
const value = useMemo(() => ({ user, setUser }), [user]);
return (
<UserContext.Provider value={value}>
{children}
</UserContext.Provider>
);
}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