Context API
Creating contexts, provider patterns, avoiding re-renders, and when to use context.
Overview
Context provides a way to pass data through the component tree without prop drilling.
Key Concepts
- createContext — Creates a context object with a default value
- Provider — Wraps components that need access to context
- useContext — Consumes context in function components
- Context Splitting — Separate providers for state and dispatch to optimize re-renders
- When to Use — Theme, auth, locale, and other app-wide state
Code Examples
import { createContext, useContext, useReducer } from 'react';
const AuthContext = createContext(null);
const AuthDispatchContext = createContext(null);
function authReducer(state, action) {
switch (action.type) {
case 'LOGIN':
return { user: action.payload, isAuthenticated: true };
case 'LOGOUT':
return { user: null, isAuthenticated: false };
default:
return state;
}
}
export function AuthProvider({ children }) {
const [state, dispatch] = useReducer(authReducer, {
user: null,
isAuthenticated: false
});
return (
<AuthContext.Provider value={state}>
<AuthDispatchContext.Provider value={dispatch}>
{children}
</AuthDispatchContext.Provider>
</AuthContext.Provider>
);
}
export function useAuth() {
const context = useContext(AuthContext);
if (!context) throw new Error('useAuth must be used within AuthProvider');
return context;
}
Practice
Create an authentication context with login/logout functionality and protected routes.