Context API Deep Dive
The Context API provides a way to pass data through the component tree without explicit prop drilling. createContext creates a context, Provider supplies a value, and useContext consumes it.
Context is a building's PA system — everyone hears every announcement. A state management library is a phone system — each person only gets calls meant for them.
Context is not a state management solution — it's a dependency injection mechanism. It doesn't manage state; it just transports it. You still need useState or useReducer to hold the state. The performance issue is that all consumers re-render when the provider value changes. Strategies: split contexts by update frequency, memoize the value, use children pattern to prevent parent re-renders. React.memo does NOT block context-triggered re-renders.
Context uses a provider-consumer model where React maintains a stack of provider values. When a consumer renders, it walks up the fiber tree to find the nearest matching provider. If no provider is found, the default value from createContext is used (not undefined — a common misunderstanding). For high-frequency updates, consider useSyncExternalStore with an external store (like Zustand or Jotai) that enables granular subscriptions. React 19 simplifies the API: <MyContext value={...}> works directly, no .Provider needed.
Context is a dependency injection mechanism, not state management — it transports state that's managed by useState or useReducer. I split contexts by update frequency to prevent unnecessary re-renders. For high-frequency updates like cursor position, I use external stores with useSyncExternalStore for selective subscriptions instead of context.
Thinking Context replaces Redux or Zustand. Context re-renders ALL consumers on any change; state management libraries provide selective subscriptions. Context is for low-frequency data like theme, locale, auth.