Server Component Context Limitations
React Context has important constraints in Server Components: Server Components cannot create or consume Context with React APIs such as `createContext` and `useContext`. A common pattern is to define the context in a Client Component and place its provider around the parts of the tree that need it.
In React Server Components, rendering happens in a server environment, where the normal interactive client-side Context model is not available. Server Components therefore cannot directly create a Context provider with `createContext` or read a context value with `useContext`.
The usual solution is to put the Context definition and provider in a Client Component. That component can use `createContext`, `useContext`, state, effects, or other client-only APIs, and its provider can wrap descendant Client Components that consume the context.
This creates an important boundary: passing data from a Server Component into a Client Component is supported through the Client Component's props, while Context is primarily used within the client-side subtree. A Server Component can render a Client Component provider, but it should not attempt to consume that provider's context itself.
For application architecture, this means Context is not a general replacement for passing server-fetched data through Server Components. Server data can often be fetched in Server Components and passed as serializable props to Client Components, while Context can manage client-side state or dependencies below the client boundary.
Key points
- Server Components cannot directly use `createContext` or `useContext`.
- Define Context providers in Client Components.
- A Server Component can render a Client Component provider around descendants.
- Use props to pass server-derived data across a Server-to-Client boundary.
- Client Context is most useful for state or dependencies consumed within the client subtree.
Interview questions
Why can't a Server Component simply read a context value provided by a Client Component?
The Server Component and Client Component participate in different execution environments and rendering boundaries. Client Context is part of the client-side React tree, so it is not a mechanism for injecting values backward into server rendering. The server-rendered portion must obtain its data through server-appropriate mechanisms and can pass supported values down into Client Components.
Can a Server Component use React Context?
No. Server Components cannot directly create or consume React Context using `createContext` and `useContext`. Context providers are instead placed in Client Components. A Server Component can render such a provider and its descendants, but it cannot consume that context itself.
How would you provide a theme or authentication-related client value to components in an RSC application?
I would define the Context and its provider in a Client Component. A Server Component can render that provider around the relevant subtree, and Client Components beneath it can consume the context. I would keep the provider as low in the tree as practical so that unrelated components do not need to become part of the client-side subtree.
If a Server Component has data that a Client Component needs, should you use Context?
Not necessarily. If the data is naturally associated with the Server Component, passing it as props to the Client Component is usually the direct approach. Context becomes useful when multiple Client Components need the same value without repeatedly threading it through props. The data crossing the Server-to-Client boundary also needs to satisfy the framework's supported serialization requirements.
What architectural mistake can result from using Context around the entire application just to share a small client-side value?
A broad provider can unnecessarily expand the portion of the application that depends on Client Components. That can reduce the benefits of keeping components server-rendered and can make the client boundary larger than necessary. I would scope the provider to the smallest subtree that actually needs the shared client state.