React's Context API is powerful for sharing data across an application. But when misused, it causes cascading re-renders, degrades performance and makes code hard to evolve.
đź”´Most Frequent Mistakes
1. God Context Anti-Pattern
Grouping everything (auth, theme, preferences, data) in a single context. Any state change triggers all consuming components, even if they only need a fraction of the data.
❌ Bad: <AppContext.Provider value={{ user, theme, settings, cart, notifications, ... }}>
âś… Good: AuthContext + ThemeContext + SettingsContext + CartContext
2. Volatile High-Frequency State
Storing high-frequency values (form inputs, real-time data, scroll position) in Context. Every keystroke or update triggers re-renders of all consumers.
❌ Bad: Storing searchInput in Context (re-render on every keystroke)
âś… Good: Local state with useState or uncontrolled input with useRef
3. useContext Everywhere
Using Context for everything instead of props or lifting state closer to where it's needed. Context is not a replacement for good component architecture.
❌ Bad: Passing modalState via Context to 2 sibling components
âś… Good: Lift state to parent and pass as props
4. Unstable References
Creating new objects or functions in Provider without memoization. Every render creates new references, triggering re-renders of all consumers.
❌ Bad: value={{ user, login: () => {...} }}
âś… Good: value={useMemo(() => ({ user, login }), [user])}
5. Coupled Read/Write
Mixing state and mutations in the same context. Components that only need actions are forced to re-render when state changes.
❌ Bad: value={{ todos, addTodo, deleteTodo }} (re-renders all consumers on state change)
âś… Good: Separate TodosContext (state) and TodosAPIContext (actions)
âś…Best Practices
1. Specialized Contexts
Split your contexts by domain: AuthContext, ThemeContext, SettingsContext, CartContext. Each component only subscribes to what it needs.
2. Dual Context Pattern
Separate API (stable functions) and State (mutable data) into two contexts:
- Context A (API): Stable functions, never re-renders
- Context B (State): Mutable data, only re-renders state consumers
- Result: Components that act import API, those that display import State
3. Memoization
Stabilize objects and functions with useMemo/useCallback to avoid creating new references on every render.
4. Props for Local State
Don't use Context if only 2-3 close components need the data. Props are simpler, more explicit and more performant.
5. Co-locate State
Keep state as close as possible to consuming components. Don't lift it to Context unless truly necessary.
🔵Dual Context Pattern in Detail
Context A: API (Actions)
- •Stable functions (login, logout, updateTheme...)
- •Never re-renders consuming components
- •Wrapped with useCallback to ensure stability
- •Imported by components that perform actions
Context B: State (Data)
- •Mutable data (user, theme, cart...)
- •Re-renders only components consuming this state
- •Optimized with useMemo if object/array
- •Imported by components that display data
Result:
Components that perform actions import the API context and never re-render on state changes. Components that display data import the State context and only re-render when that specific state changes.
When to Use (or Not Use) Context
âś… Good Use Cases
- • Global data (auth, theme, locale)
- • Data consumed by many distant components
- • Avoiding prop drilling (5+ levels)
- • Stable configurations
- • User preferences
❌ Bad Use Cases
- • Volatile high-frequency state (inputs)
- • Real-time data (websockets, intervals)
- • Data for only 2-3 close components
- • As state management replacement
- • Complex state logic (use Zustand, Jotai)
Performance Checklist
- Split God Context into specialized contexts by domain
- Separate API and State into Dual Context pattern
- Memoize context values with useMemo/useCallback
- Remove volatile state from Context (use local state)
- Verify no unnecessary useContext calls (use props if close)
- Test performance with React DevTools Profiler
- Consider state library (Zustand, Jotai) for complex logic
Need Help Optimizing Your React Application?
VOID's React experts audit and optimize your architecture for maximum performance