Split contexts, memoized providers, and selector patterns to avoid re-render storms. React Context is built-in and works for infrequently changing values - theme, locale, auth session. A single mega-context updating every second will tank list scroll performance on mid-range Android devices.
Single context with { state, dispatch, extras } - Every dispatch re-renders readers of extras. Fix: Split state and actions.
Inline functions in provider value - signOut: () => setUser(null) breaks React.memo. Fix:useCallback.
Storing fetched arrays in Context - Refetch updates re-render the tree. Fix: TanStack Query.
Provider inside FlatList renderItem - N providers per row. Fix: One provider at app/_layout.tsx.
Default context value with real data - createContext({ user: guest }) masks missing provider. Fix:null + throw in hook.
useSyncExternalStore selector without store subscription - Example above still re-renders when parent context updates - true fine-grained needs external store (Zustand/Jotai).
Passing entire API client in Context - Stable but encourages fat context. Fix: Module singleton or DI - see dependency injection.
Context itself is fast - unnecessary consumers are slow. Split contexts, memoize values, and avoid putting high-frequency state in Context.
How many providers at root is too many?
Three to five well-scoped providers is normal (Query, Session, Theme, SafeArea). More than eight nested suggests consolidation.
Should I use Context for React Navigation theme?
Expo Router / React Navigation accept a theme prop on the root navigator - often simpler than custom Context for colors alone.
Context vs Zustand for auth?
Both work. Context + expo-secure-store adapter is common. Zustand helps when many selectors read auth-adjacent UI flags - see ADR Decision 7.
How do I test providers?
Wrap with SessionProvider in tests; mock secure store at boundary. Prefer testing hooks with renderHook and stubbed context values.
Does React 19 improve Context?
React 19 continues concurrent rendering - context consumers still re-render when value changes. Splitting and selectors remain best practice on RN 0.86.
Can I combine useReducer with Context?
Yes - useReducer in provider, split dispatch into actions context. Pattern matches Redux without the dependency.
What about React.memo on list items?
Memo helps only if props are stable. Fix the provider first - memo on 200 rows is a band-aid on a storm.
Should locale live in Context?
Yes - i18n direction and strings change infrequently. Pair with expo-localization for device default; persist user override in AsyncStorage.
How do I debug re-render storms?
React DevTools Profiler ā record interaction ā find cascading renders from one context provider. Flip one split at a time.
Is passing dispatch via Context OK?
dispatch is stable - safe in actions context. Consumers that only dispatch never need state context.
When is one combined context acceptable?
Prototypes and apps with <10 screens where profiler shows no list jank. Refactor before shipping long lists.