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); } }