Context Splitting

Context splitting separates unrelated state into different React contexts so consumers subscribe only to the values they need. This can reduce unnecessary re-renders when one piece of context state changes without requiring every consumer to update.

React context provides a value to all consumers beneath a provider. When the provider's `value` changes, consumers of that context are considered for re-rendering, even when a particular consumer only uses one field from the value.

Context splitting addresses this by dividing logically independent values into separate contexts. For example, authentication state, theme settings, and locale can use distinct contexts rather than sharing one large context object. A change to the theme then does not make components that consume only authentication state context consumers of the theme context.

Splitting is most useful when values have different update frequencies or different consumer sets. It is less valuable when values always change together or are almost always consumed together, because excessive contexts can make component composition and dependency tracking harder.

Context splitting is different from merely splitting a provider component into smaller components. The optimization comes from separating subscriptions: consumers of `AuthContext` are distinct from consumers of `ThemeContext`. Stable provider values and appropriate memoization can complement this approach when provider values contain objects or functions.

Key points

Interview questions

What is context splitting, and why would you use it?

Context splitting means putting unrelated pieces of shared state into separate React contexts. It is useful because a component can subscribe only to the context containing the data it needs. For example, theme and authentication state can have separate contexts. This makes the update boundaries clearer and can reduce unnecessary consumer updates when one state changes independently of another.

Does putting two values in separate contexts always prevent unnecessary re-renders?

It prevents a consumer of one context from subscribing to changes in a different context. However, it does not solve every rendering problem in the provider subtree. Provider components themselves can re-render for other reasons, and unstable objects or functions passed as a context value can cause that context's consumers to update. Therefore, context splitting should be considered alongside component structure and value stability.

How would you decide whether two values belong in the same context?

I would look at their ownership, update frequency, and consumer sets. If they change together and are consumed together, keeping them together can be simpler. If they have different lifecycles, update frequently at different rates, or are used by substantially different components, separate contexts can create better boundaries. I would also consider provider nesting and maintainability so that a performance optimization does not make the architecture harder to understand.

How is context splitting different from using context selectors?

Context splitting creates multiple context subscription boundaries, so each consumer subscribes to a separately defined value. Selector-based approaches instead allow multiple consumers to derive selected portions from a shared state source. Splitting is straightforward when the state naturally falls into a small number of independent domains. Selectors can be more granular when many consumers need different slices of a larger state object.

You have a context containing user data, feature flags, notifications, and theme state. How would you improve it?

I would first inspect which components consume each part and how frequently each value changes. If these domains have largely different consumers or update independently, I would split them into separate contexts such as user, flags, notifications, and theme. I would also inspect the provider values for unstable object and function identities and stabilize them where appropriate. Finally, I would measure rendering behavior rather than assuming that splitting alone is necessary.