Context causes re-renders for all consumers on any change. Here's how to optimize with selectors.
The Problem#
Solution 1: Split Contexts#
Solution 2: Selector Hook with useSyncExternalStore#
Solution 3: Context with Ref and Subscription#
Solution 4: Memoized Context Value#
Solution 5: Higher-Order Component Selector#
Zustand-Style Implementation#
Performance Comparison#
Best Practices#
Strategies:
✓ Split contexts by update frequency
✓ Use selectors for granular subscriptions
✓ Memoize context values
✓ Consider external state libraries
Performance:
✓ Keep selectors simple
✓ Return primitive values when possible
✓ Use shallow comparison
✓ Avoid creating objects in selectors
Libraries:
✓ Zustand for simple state
✓ Jotai for atomic state
✓ use-context-selector for existing contexts
✓ React Query for server state
Conclusion#
Context selectors prevent unnecessary re-renders by subscribing to specific state slices. Split contexts for different domains, use useSyncExternalStore for selector patterns, or adopt libraries like Zustand. The right approach depends on your app's complexity and update patterns.