React Context for State Sharing

React Context lets a component expose a value to its descendant tree without threading that value through every intermediate component as props. It is useful for shared concerns such as theme, locale, authentication state, and other values consumed by multiple components.

Context consists of a context object, a provider, and consumers. You create a context with `createContext`, place a provider above the components that need the value, and read the current value with `useContext` in function components.

A provider supplies its value to all descendant consumers. Components between the provider and consumers do not need to receive or forward that value as props, which avoids prop drilling.

When a provider's `value` changes, React updates components that consume that context. This means context is not inherently a performance optimization: placing frequently changing state in a broadly used context can cause many consumers to re-render.

Context does not replace every form of state management. Local component state is usually simpler for state confined to one component subtree, while context is useful when many descendants need the same dependency. For complex shared state, context is often paired with `useReducer` or another state-management approach.

Key points

Interview questions

How do you create and consume a context?

Create the context with `createContext`, then render a provider above the components that need the value. A function component can read the value with `useContext` and the context object. The consumer receives the value from the nearest matching provider in the component tree. If no provider is found, React uses the context's default value.

What problem does React Context solve?

Context solves the need to make a value available to many descendants without passing it through every intermediate component as a prop. A provider establishes the value, and consumers read it from the nearest matching provider. This is commonly useful for shared concerns such as themes or locale. It does not mean every application value should be placed in context.

What happens when a Context provider's value changes?

React updates components that consume that context when the provider's value changes. The update is tied to the context value rather than to whether intermediate components receive the value as props. Consequently, a context containing frequently changing data can affect many consumers. Splitting contexts or structuring the shared state carefully can reduce unnecessary work.

When would you use Context instead of passing props?

Context is useful when the same value is needed by multiple descendants and passing it through intermediate components would add unnecessary plumbing. Props are often clearer when data is needed by only a few direct or nearby components. Context also makes the dependency less explicit at intermediate boundaries, so it should not automatically replace props. The choice depends on the scope and ownership of the data.

How would you improve the performance of a context-heavy application?

First, identify which consumers actually need each value and avoid putting unrelated state into one large context. Frequently changing values can be split into separate contexts so consumers subscribe only to relevant changes. Stable provider values can also help avoid updates caused by changing object identity when the underlying data has not meaningfully changed. For more demanding state-sharing requirements, a dedicated state-management approach with finer-grained subscriptions may be appropriate.