diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
index 3d00423c9a081..3707f61b82a48 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
@@ -5215,6 +5215,54 @@ describe('ReactDOMFizzServer', () => {
expect(getVisibleChildren(container)).toEqual('ABC');
});
+ // @gate enableUseHook
+ it('basic use(context)', async () => {
+ const ContextA = React.createContext('default');
+ const ContextB = React.createContext('B');
+ const ServerContext = React.createServerContext(
+ 'ServerContext',
+ 'default',
+ );
+ function Client() {
+ return use(ContextA) + use(ContextB);
+ }
+ function ServerComponent() {
+ return use(ServerContext);
+ }
+ function Server() {
+ return (
+
+
+
+ );
+ }
+ function App() {
+ return (
+ <>
+
+
+
+
+ >
+ );
+ }
+
+ await act(async () => {
+ const {pipe} = renderToPipeableStream();
+ pipe(writable);
+ });
+ expect(getVisibleChildren(container)).toEqual(['AB', 'C']);
+
+ // Hydration uses a different renderer runtime (Fiber instead of Fizz).
+ // We reset _currentRenderer here to not trigger a warning about multiple
+ // renderers concurrently using these contexts
+ ContextA._currentRenderer = null;
+ ServerContext._currentRenderer = null;
+ ReactDOMClient.hydrateRoot(container, );
+ expect(Scheduler).toFlushAndYield([]);
+ expect(getVisibleChildren(container)).toEqual(['AB', 'C']);
+ });
+
// @gate enableUseHook
it('use(promise) in multiple components', async () => {
const promiseA = Promise.resolve('A');
diff --git a/packages/react-server/src/ReactFizzHooks.js b/packages/react-server/src/ReactFizzHooks.js
index 39f0af172fabe..f404a71c6ad5f 100644
--- a/packages/react-server/src/ReactFizzHooks.js
+++ b/packages/react-server/src/ReactFizzHooks.js
@@ -40,7 +40,11 @@ import {
enableUseMemoCacheHook,
} from 'shared/ReactFeatureFlags';
import is from 'shared/objectIs';
-import {REACT_MEMO_CACHE_SENTINEL} from 'shared/ReactSymbols';
+import {
+ REACT_SERVER_CONTEXT_TYPE,
+ REACT_CONTEXT_TYPE,
+ REACT_MEMO_CACHE_SENTINEL,
+} from 'shared/ReactSymbols';
type BasicStateAction = (S => S) | S;
type Dispatch = A => void;
@@ -644,8 +648,12 @@ function use(usable: Usable): T {
}
}
}
- } else {
- // TODO: Add support for Context
+ } else if (
+ usable.$$typeof === REACT_CONTEXT_TYPE ||
+ usable.$$typeof === REACT_SERVER_CONTEXT_TYPE
+ ) {
+ const context: ReactContext = (usable: any);
+ return readContext(context);
}
}