diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index a62fb685fbc06..8ed9762bb7666 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -48,8 +48,6 @@ import { REACT_POSTPONE_TYPE, } from 'shared/ReactSymbols'; -import {getOrCreateServerContext} from 'shared/ReactServerContextRegistry'; - export type {CallServerCallback}; type UninitializedModel = string; @@ -634,10 +632,6 @@ function parseModelString( // Symbol return Symbol.for(value.slice(2)); } - case 'P': { - // Server Context Provider - return getOrCreateServerContext(value.slice(2)).Provider; - } case 'F': { // Server Reference const id = parseInt(value.slice(2), 16); diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index 8e038bfc0f805..8ac4ab404f1cd 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -122,32 +122,6 @@ describe('ReactFlight', () => { jest.restoreAllMocks(); }); - function createServerContext(globalName, defaultValue, withStack) { - let ctx; - expect(() => { - ctx = React.createServerContext(globalName, defaultValue); - }).toErrorDev( - 'Server Context is deprecated and will soon be removed. ' + - 'It was never documented and we have found it not to be useful ' + - 'enough to warrant the downside it imposes on all apps.', - {withoutStack: !withStack}, - ); - return ctx; - } - - function createServerServerContext(globalName, defaultValue, withStack) { - let ctx; - expect(() => { - ctx = ReactServer.createServerContext(globalName, defaultValue); - }).toErrorDev( - 'Server Context is deprecated and will soon be removed. ' + - 'It was never documented and we have found it not to be useful ' + - 'enough to warrant the downside it imposes on all apps.', - {withoutStack: !withStack}, - ); - return ctx; - } - function clientReference(value) { return Object.defineProperties( function () { @@ -1042,18 +1016,50 @@ describe('ReactFlight', () => { ]); }); - it('should warn in DEV if a a client reference is passed to useContext()', () => { + it('should error if useContext is called()', () => { + function ServerComponent() { + return ReactServer.useContext(); + } + const errors = []; + ReactNoopFlightServer.render(, { + onError(x) { + errors.push(x.message); + }, + }); + expect(errors).toEqual(['ReactServer.useContext is not a function']); + }); + + it('should error if a context without a client reference is passed to use()', () => { + const Context = React.createContext(); + function ServerComponent() { + return ReactServer.use(Context); + } + const errors = []; + ReactNoopFlightServer.render(, { + onError(x) { + errors.push(x.message); + }, + }); + expect(errors).toEqual([ + 'Cannot read a Client Context from a Server Component.', + ]); + }); + + it('should error if a client reference is passed to use()', () => { const Context = React.createContext(); const ClientContext = clientReference(Context); function ServerComponent() { - return ReactServer.useContext(ClientContext); + return ReactServer.use(ClientContext); } - expect(() => { - const transport = ReactNoopFlightServer.render(); - ReactNoopFlightClient.read(transport); - }).toErrorDev('Cannot read a Client Context from a Server Component.', { - withoutStack: true, + const errors = []; + ReactNoopFlightServer.render(, { + onError(x) { + errors.push(x.message); + }, }); + expect(errors).toEqual([ + 'Cannot read a Client Context from a Server Component.', + ]); }); describe('Hooks', () => { @@ -1149,360 +1155,6 @@ describe('ReactFlight', () => { }); }); - describe('ServerContext', () => { - // @gate enableServerContext - it('supports basic createServerContext usage', async () => { - const ServerContext = createServerServerContext( - 'ServerContext', - 'hello from server', - ); - function Foo() { - const context = ReactServer.useContext(ServerContext); - return
{context}
; - } - - const transport = ReactNoopFlightServer.render(); - await act(async () => { - ReactNoop.render(await ReactNoopFlightClient.read(transport)); - }); - - expect(ReactNoop).toMatchRenderedOutput(
hello from server
); - }); - - // @gate enableServerContext - it('propagates ServerContext providers in flight', async () => { - const ServerContext = createServerServerContext( - 'ServerContext', - 'default', - ); - - function Foo() { - return ( -
- - - -
- ); - } - function Bar() { - const context = ReactServer.useContext(ServerContext); - return context; - } - - const transport = ReactNoopFlightServer.render(); - await act(async () => { - ReactNoop.render(await ReactNoopFlightClient.read(transport)); - }); - - expect(ReactNoop).toMatchRenderedOutput(
hi this is server
); - }); - - // @gate enableServerContext - it('errors if you try passing JSX through ServerContext value', () => { - const ServerContext = createServerServerContext('ServerContext', { - foo: { - bar: hi this is default, - }, - }); - - function Foo() { - return ( -
- hi this is server, - }, - }}> - - -
- ); - } - function Bar() { - const context = ReactServer.useContext(ServerContext); - return context.foo.bar; - } - - expect(() => { - ReactNoopFlightServer.render(); - }).toErrorDev('React elements are not allowed in ServerContext', { - withoutStack: true, - }); - }); - - // @gate enableServerContext - it('propagates ServerContext and cleans up the providers in flight', async () => { - const ServerContext = createServerServerContext( - 'ServerContext', - 'default', - ); - - function Foo() { - return ( - <> - - - - - - - - - - - - - - - ); - } - function Bar() { - const context = ReactServer.useContext(ServerContext); - return {context}; - } - - const transport = ReactNoopFlightServer.render(); - await act(async () => { - ReactNoop.render(await ReactNoopFlightClient.read(transport)); - }); - - expect(ReactNoop).toMatchRenderedOutput( - <> - hi this is server - hi this is server2 - hi this is server outer - hi this is server outer2 - default - , - ); - }); - - // @gate enableServerContext - it('propagates ServerContext providers in flight after suspending', async () => { - const ServerContext = createServerServerContext( - 'ServerContext', - 'default', - ); - - function Foo() { - return ( -
- - - - - -
- ); - } - - let resolve; - const promise = new Promise(res => { - resolve = () => { - promise.unsuspend = true; - res(); - }; - }); - - function Bar() { - if (!promise.unsuspend) { - Scheduler.log('suspended'); - throw promise; - } - Scheduler.log('rendered'); - const context = ReactServer.useContext(ServerContext); - return context; - } - - const transport = ReactNoopFlightServer.render(); - - assertLog(['suspended']); - - await act(async () => { - resolve(); - await promise; - jest.runAllImmediates(); - }); - - assertLog(['rendered']); - - await act(async () => { - ReactNoop.render(await ReactNoopFlightClient.read(transport)); - }); - - expect(ReactNoop).toMatchRenderedOutput(
hi this is server
); - }); - - // @gate enableServerContext - it('serializes ServerContext to client', async () => { - const ServerContext = createServerServerContext( - 'ServerContext', - 'default', - ); - const ClientContext = createServerContext('ServerContext', 'default'); - - function ClientBar() { - Scheduler.log('ClientBar'); - const context = React.useContext(ClientContext); - return {context}; - } - - const Bar = clientReference(ClientBar); - - function Foo() { - return ( - - - - ); - } - - const model = { - foo: , - }; - - const transport = ReactNoopFlightServer.render(model); - - assertLog([]); - - await act(async () => { - const flightModel = await ReactNoopFlightClient.read(transport); - ReactNoop.render(flightModel.foo); - }); - - assertLog(['ClientBar']); - expect(ReactNoop).toMatchRenderedOutput(hi this is server); - - expect(() => { - createServerContext('ServerContext', 'default'); - }).toThrow('ServerContext: ServerContext already defined'); - }); - - // @gate enableServerContext - it('takes ServerContext from the client for refetching use cases', async () => { - const ServerContext = createServerServerContext( - 'ServerContext', - 'default', - ); - function Bar() { - return {ReactServer.useContext(ServerContext)}; - } - const transport = ReactNoopFlightServer.render(, { - context: [['ServerContext', 'Override']], - }); - - await act(async () => { - const flightModel = await ReactNoopFlightClient.read(transport); - ReactNoop.render(flightModel); - }); - expect(ReactNoop).toMatchRenderedOutput(Override); - }); - - // @gate enableServerContext - it('sets default initial value when defined lazily on server or client', async () => { - let ServerContext; - function inlineLazyServerContextInitialization() { - if (!ServerContext) { - ServerContext = createServerServerContext('ServerContext', 'default'); - } - return ServerContext; - } - - let ClientContext; - function inlineContextInitialization() { - if (!ClientContext) { - ClientContext = createServerContext('ServerContext', 'default', true); - } - return ClientContext; - } - - function ClientBaz() { - const context = inlineContextInitialization(); - const value = React.useContext(context); - return
{value}
; - } - - const Baz = clientReference(ClientBaz); - - function Bar() { - return ( -
-
- {ReactServer.useContext(inlineLazyServerContextInitialization())} -
- -
- ); - } - - function ServerApp() { - const Context = inlineLazyServerContextInitialization(); - return ( - <> - - - - - - ); - } - - function ClientApp({serverModel}) { - return ( - <> - {serverModel} - - - ); - } - - const transport = ReactNoopFlightServer.render(); - - expect(ClientContext).toBe(undefined); - - // Reset all modules, except flight-modules which keeps the registry of Client Components - const flightModules = require('react-noop-renderer/flight-modules'); - jest.resetModules(); - jest.mock('react', () => require('react/react.react-server')); - jest.mock('react-noop-renderer/flight-modules', () => flightModules); - - ReactServer = require('react'); - ReactNoopFlightServer = require('react-noop-renderer/flight-server'); - - __unmockReact(); - jest.resetModules(); - jest.mock('react-noop-renderer/flight-modules', () => flightModules); - React = require('react'); - ReactNoop = require('react-noop-renderer'); - ReactNoopFlightClient = require('react-noop-renderer/flight-client'); - act = require('internal-test-utils').act; - Scheduler = require('scheduler'); - - await act(async () => { - const serverModel = await ReactNoopFlightClient.read(transport); - ReactNoop.render(); - }); - - expect(ClientContext).not.toBe(ServerContext); - - expect(ReactNoop).toMatchRenderedOutput( - <> -
-
test
-
test
-
-
-
default
-
default
-
-
default
- , - ); - }); - }); - // @gate enableTaint it('errors when a tainted object is serialized', async () => { function UserClient({user}) { diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js index da250d55558fe..5a796c5446f06 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js @@ -3353,62 +3353,6 @@ describe('ReactDOMFizzServer', () => { ]); }); - // @gate enableServerContext - it('supports ServerContext', async () => { - let ServerContext; - function inlineLazyServerContextInitialization() { - if (!ServerContext) { - expect(() => { - ServerContext = React.createServerContext('ServerContext', 'default'); - }).toErrorDev( - 'Server Context is deprecated and will soon be removed. ' + - 'It was never documented and we have found it not to be useful ' + - 'enough to warrant the downside it imposes on all apps.', - ); - } - return ServerContext; - } - - function Foo() { - React.useState(); // component stack generation shouldn't reinit - inlineLazyServerContextInitialization(); - return ( - <> - - - - - - - - - - - - - - - ); - } - function Bar() { - const context = React.useContext(inlineLazyServerContextInitialization()); - return {context}; - } - - await act(() => { - const {pipe} = renderToPipeableStream(); - pipe(writable); - }); - - expect(getVisibleChildren(container)).toEqual([ - hi this is server, - hi this is server2, - hi this is server outer, - hi this is server outer2, - default, - ]); - }); - it('Supports iterable', async () => { const Immutable = require('immutable'); @@ -5886,39 +5830,18 @@ describe('ReactDOMFizzServer', () => { expect(getVisibleChildren(container)).toEqual('ABC'); }); - // @gate enableServerContext it('basic use(context)', async () => { const ContextA = React.createContext('default'); const ContextB = React.createContext('B'); - let ServerContext; - expect(() => { - ServerContext = React.createServerContext('ServerContext', 'default'); - }).toErrorDev( - 'Server Context is deprecated and will soon be removed. ' + - 'It was never documented and we have found it not to be useful ' + - 'enough to warrant the downside it imposes on all apps.', - {withoutStack: true}, - ); function Client() { return use(ContextA) + use(ContextB); } - function ServerComponent() { - return use(ServerContext); - } - function Server() { - return ( - - - - ); - } function App() { return ( <> - ); } @@ -5927,16 +5850,15 @@ describe('ReactDOMFizzServer', () => { const {pipe} = renderToPipeableStream(); pipe(writable); }); - expect(getVisibleChildren(container)).toEqual(['AB', 'C']); + expect(getVisibleChildren(container)).toEqual('AB'); // 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, ); await waitForAll([]); - expect(getVisibleChildren(container)).toEqual(['AB', 'C']); + expect(getVisibleChildren(container)).toEqual('AB'); }); it('use(promise) in multiple components', async () => { diff --git a/packages/react-is/src/ReactIs.js b/packages/react-is/src/ReactIs.js index 7df6bc0280516..eb68e2cbaceed 100644 --- a/packages/react-is/src/ReactIs.js +++ b/packages/react-is/src/ReactIs.js @@ -11,7 +11,6 @@ import { REACT_CONTEXT_TYPE, - REACT_SERVER_CONTEXT_TYPE, REACT_ELEMENT_TYPE, REACT_FORWARD_REF_TYPE, REACT_FRAGMENT_TYPE, @@ -44,7 +43,6 @@ export function typeOf(object: any): mixed { const $$typeofType = type && type.$$typeof; switch ($$typeofType) { - case REACT_SERVER_CONTEXT_TYPE: case REACT_CONTEXT_TYPE: case REACT_FORWARD_REF_TYPE: case REACT_LAZY_TYPE: diff --git a/packages/react-noop-renderer/src/ReactNoopFlightServer.js b/packages/react-noop-renderer/src/ReactNoopFlightServer.js index 9faab3cdfa110..41bdcd3d6b0d4 100644 --- a/packages/react-noop-renderer/src/ReactNoopFlightServer.js +++ b/packages/react-noop-renderer/src/ReactNoopFlightServer.js @@ -15,7 +15,6 @@ */ import type {ReactClientValue} from 'react-server/src/ReactFlightServer'; -import type {ServerContextJSONValue} from 'shared/ReactTypes'; import {saveModule} from 'react-noop-renderer/flight-modules'; @@ -70,7 +69,6 @@ const ReactNoopFlightServer = ReactFlightServer({ type Options = { onError?: (error: mixed) => void, - context?: Array<[string, ServerContextJSONValue]>, identifierPrefix?: string, }; @@ -81,7 +79,6 @@ function render(model: ReactClientValue, options?: Options): Destination { model, bundlerConfig, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, ); ReactNoopFlightServer.startWork(request); diff --git a/packages/react-reconciler/src/ReactChildFiber.js b/packages/react-reconciler/src/ReactChildFiber.js index 8c907da9345b1..236ef7f37136f 100644 --- a/packages/react-reconciler/src/ReactChildFiber.js +++ b/packages/react-reconciler/src/ReactChildFiber.js @@ -27,7 +27,6 @@ import { REACT_PORTAL_TYPE, REACT_LAZY_TYPE, REACT_CONTEXT_TYPE, - REACT_SERVER_CONTEXT_TYPE, } from 'shared/ReactSymbols'; import {ClassComponent, HostText, HostPortal, Fragment} from './ReactWorkTags'; import isArray from 'shared/isArray'; @@ -577,10 +576,7 @@ function createChildReconciler( return createChild(returnFiber, unwrapThenable(thenable), lanes); } - if ( - newChild.$$typeof === REACT_CONTEXT_TYPE || - newChild.$$typeof === REACT_SERVER_CONTEXT_TYPE - ) { + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { const context: ReactContext = (newChild: any); return createChild( returnFiber, @@ -667,10 +663,7 @@ function createChildReconciler( ); } - if ( - newChild.$$typeof === REACT_CONTEXT_TYPE || - newChild.$$typeof === REACT_SERVER_CONTEXT_TYPE - ) { + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { const context: ReactContext = (newChild: any); return updateSlot( returnFiber, @@ -756,10 +749,7 @@ function createChildReconciler( ); } - if ( - newChild.$$typeof === REACT_CONTEXT_TYPE || - newChild.$$typeof === REACT_SERVER_CONTEXT_TYPE - ) { + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { const context: ReactContext = (newChild: any); return updateFromMap( existingChildren, @@ -1442,10 +1432,7 @@ function createChildReconciler( ); } - if ( - newChild.$$typeof === REACT_CONTEXT_TYPE || - newChild.$$typeof === REACT_SERVER_CONTEXT_TYPE - ) { + if (newChild.$$typeof === REACT_CONTEXT_TYPE) { const context: ReactContext = (newChild: any); return reconcileChildFibersImpl( returnFiber, diff --git a/packages/react-reconciler/src/ReactFiberCacheComponent.js b/packages/react-reconciler/src/ReactFiberCacheComponent.js index b80091a76acf1..64269c5785d13 100644 --- a/packages/react-reconciler/src/ReactFiberCacheComponent.js +++ b/packages/react-reconciler/src/ReactFiberCacheComponent.js @@ -73,8 +73,6 @@ export const CacheContext: ReactContext = enableCache _currentValue: (null: any), _currentValue2: (null: any), _threadCount: 0, - _defaultValue: (null: any), - _globalName: (null: any), } : (null: any); diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 2ace73aa69ad6..742da1577bc71 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -46,7 +46,6 @@ import { } from 'shared/ReactFeatureFlags'; import { REACT_CONTEXT_TYPE, - REACT_SERVER_CONTEXT_TYPE, REACT_MEMO_CACHE_SENTINEL, } from 'shared/ReactSymbols'; @@ -1072,10 +1071,7 @@ function use(usable: Usable): T { // This is a thenable. const thenable: Thenable = (usable: any); return useThenable(thenable); - } else if ( - usable.$$typeof === REACT_CONTEXT_TYPE || - usable.$$typeof === REACT_SERVER_CONTEXT_TYPE - ) { + } else if (usable.$$typeof === REACT_CONTEXT_TYPE) { const context: ReactContext = (usable: any); return readContext(context); } diff --git a/packages/react-reconciler/src/ReactFiberHostContext.js b/packages/react-reconciler/src/ReactFiberHostContext.js index d909002dc97f2..3ba99edb239ad 100644 --- a/packages/react-reconciler/src/ReactFiberHostContext.js +++ b/packages/react-reconciler/src/ReactFiberHostContext.js @@ -51,8 +51,6 @@ export const HostTransitionContext: ReactContext = { _threadCount: 0, Provider: (null: any), Consumer: (null: any), - _defaultValue: (null: any), - _globalName: (null: any), }; function requiredContext(c: Value | null): Value { diff --git a/packages/react-reconciler/src/ReactFiberNewContext.js b/packages/react-reconciler/src/ReactFiberNewContext.js index d4f4eb048e43b..0aec54348c2cd 100644 --- a/packages/react-reconciler/src/ReactFiberNewContext.js +++ b/packages/react-reconciler/src/ReactFiberNewContext.js @@ -44,11 +44,9 @@ import {createUpdate, ForceUpdate} from './ReactFiberClassUpdateQueue'; import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork'; import { enableLazyContextPropagation, - enableServerContext, enableFormActions, enableAsyncActions, } from 'shared/ReactFeatureFlags'; -import {REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED} from 'shared/ReactSymbols'; import { getHostTransitionProvider, HostTransitionContext, @@ -153,28 +151,14 @@ export function popProvider( const currentValue = valueCursor.current; if (isPrimaryRenderer) { - if ( - enableServerContext && - currentValue === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED - ) { - context._currentValue = context._defaultValue; - } else { - context._currentValue = currentValue; - } + context._currentValue = currentValue; if (__DEV__) { const currentRenderer = rendererCursorDEV.current; pop(rendererCursorDEV, providerFiber); context._currentRenderer = currentRenderer; } } else { - if ( - enableServerContext && - currentValue === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED - ) { - context._currentValue2 = context._defaultValue; - } else { - context._currentValue2 = currentValue; - } + context._currentValue2 = currentValue; if (__DEV__) { const currentRenderer2 = renderer2CursorDEV.current; pop(renderer2CursorDEV, providerFiber); diff --git a/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js b/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js index 73944deb5bc1d..08c2ede7f8f9c 100644 --- a/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js @@ -16,7 +16,7 @@ import type {ClientManifest} from './ReactFlightServerConfigESMBundler'; import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import type {Busboy} from 'busboy'; import type {Writable} from 'stream'; -import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; +import type {Thenable} from 'shared/ReactTypes'; import { createRequest, @@ -54,7 +54,6 @@ function createDrainHandler(destination: Destination, request: Request) { type Options = { onError?: (error: mixed) => void, onPostpone?: (reason: string) => void, - context?: Array<[string, ServerContextJSONValue]>, identifierPrefix?: string, }; @@ -72,7 +71,6 @@ function renderToPipeableStream( model, moduleBasePath, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, ); diff --git a/packages/react-server-dom-turbopack/src/ReactFlightDOMServerBrowser.js b/packages/react-server-dom-turbopack/src/ReactFlightDOMServerBrowser.js index 0ac7e0f0c39d7..ed8407b312749 100644 --- a/packages/react-server-dom-turbopack/src/ReactFlightDOMServerBrowser.js +++ b/packages/react-server-dom-turbopack/src/ReactFlightDOMServerBrowser.js @@ -8,7 +8,7 @@ */ import type {ReactClientValue} from 'react-server/src/ReactFlightServer'; -import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; +import type {Thenable} from 'shared/ReactTypes'; import type {ClientManifest} from './ReactFlightServerConfigTurbopackBundler'; import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; @@ -36,7 +36,6 @@ export { type Options = { identifierPrefix?: string, signal?: AbortSignal, - context?: Array<[string, ServerContextJSONValue]>, onError?: (error: mixed) => void, onPostpone?: (reason: string) => void, }; @@ -50,7 +49,6 @@ function renderToReadableStream( model, turbopackMap, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, ); diff --git a/packages/react-server-dom-turbopack/src/ReactFlightDOMServerEdge.js b/packages/react-server-dom-turbopack/src/ReactFlightDOMServerEdge.js index 0ac7e0f0c39d7..ed8407b312749 100644 --- a/packages/react-server-dom-turbopack/src/ReactFlightDOMServerEdge.js +++ b/packages/react-server-dom-turbopack/src/ReactFlightDOMServerEdge.js @@ -8,7 +8,7 @@ */ import type {ReactClientValue} from 'react-server/src/ReactFlightServer'; -import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; +import type {Thenable} from 'shared/ReactTypes'; import type {ClientManifest} from './ReactFlightServerConfigTurbopackBundler'; import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; @@ -36,7 +36,6 @@ export { type Options = { identifierPrefix?: string, signal?: AbortSignal, - context?: Array<[string, ServerContextJSONValue]>, onError?: (error: mixed) => void, onPostpone?: (reason: string) => void, }; @@ -50,7 +49,6 @@ function renderToReadableStream( model, turbopackMap, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, ); diff --git a/packages/react-server-dom-turbopack/src/ReactFlightDOMServerNode.js b/packages/react-server-dom-turbopack/src/ReactFlightDOMServerNode.js index 0eac06aee2194..a988b79fad885 100644 --- a/packages/react-server-dom-turbopack/src/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-turbopack/src/ReactFlightDOMServerNode.js @@ -16,7 +16,7 @@ import type {ClientManifest} from './ReactFlightServerConfigTurbopackBundler'; import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import type {Busboy} from 'busboy'; import type {Writable} from 'stream'; -import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; +import type {Thenable} from 'shared/ReactTypes'; import { createRequest, @@ -51,7 +51,6 @@ function createDrainHandler(destination: Destination, request: Request) { type Options = { onError?: (error: mixed) => void, onPostpone?: (reason: string) => void, - context?: Array<[string, ServerContextJSONValue]>, identifierPrefix?: string, }; @@ -69,7 +68,6 @@ function renderToPipeableStream( model, turbopackMap, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, ); diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js b/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js index 806a286d143ba..2c5c5bcebc500 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js @@ -8,7 +8,7 @@ */ import type {ReactClientValue} from 'react-server/src/ReactFlightServer'; -import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; +import type {Thenable} from 'shared/ReactTypes'; import type {ClientManifest} from './ReactFlightServerConfigWebpackBundler'; import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; @@ -40,7 +40,6 @@ export { type Options = { identifierPrefix?: string, signal?: AbortSignal, - context?: Array<[string, ServerContextJSONValue]>, onError?: (error: mixed) => void, onPostpone?: (reason: string) => void, }; @@ -54,7 +53,6 @@ function renderToReadableStream( model, webpackMap, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, ); diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js b/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js index 806a286d143ba..2c5c5bcebc500 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js @@ -8,7 +8,7 @@ */ import type {ReactClientValue} from 'react-server/src/ReactFlightServer'; -import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; +import type {Thenable} from 'shared/ReactTypes'; import type {ClientManifest} from './ReactFlightServerConfigWebpackBundler'; import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; @@ -40,7 +40,6 @@ export { type Options = { identifierPrefix?: string, signal?: AbortSignal, - context?: Array<[string, ServerContextJSONValue]>, onError?: (error: mixed) => void, onPostpone?: (reason: string) => void, }; @@ -54,7 +53,6 @@ function renderToReadableStream( model, webpackMap, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, ); diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js b/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js index 6e9903beb9b1f..850511ab099ef 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js @@ -16,7 +16,7 @@ import type {ClientManifest} from './ReactFlightServerConfigWebpackBundler'; import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import type {Busboy} from 'busboy'; import type {Writable} from 'stream'; -import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; +import type {Thenable} from 'shared/ReactTypes'; import { createRequest, @@ -63,7 +63,6 @@ function createCancelHandler(request: Request, reason: string) { type Options = { onError?: (error: mixed) => void, onPostpone?: (reason: string) => void, - context?: Array<[string, ServerContextJSONValue]>, identifierPrefix?: string, }; @@ -81,7 +80,6 @@ function renderToPipeableStream( model, webpackMap, options ? options.onError : undefined, - options ? options.context : undefined, options ? options.identifierPrefix : undefined, options ? options.onPostpone : undefined, ); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js index efbaba033c3f9..2427317ce2c32 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js @@ -641,54 +641,6 @@ describe('ReactFlightDOMBrowser', () => { expect(container.innerHTML).toBe('ABC'); }); - // @gate enableServerContext - it('basic use(context)', async () => { - let ContextA; - let ContextB; - expect(() => { - ContextA = React.createServerContext('ContextA', ''); - ContextB = React.createServerContext('ContextB', 'B'); - }).toErrorDev( - [ - 'Server Context is deprecated and will soon be removed. ' + - 'It was never documented and we have found it not to be useful ' + - 'enough to warrant the downside it imposes on all apps.', - 'Server Context is deprecated and will soon be removed. ' + - 'It was never documented and we have found it not to be useful ' + - 'enough to warrant the downside it imposes on all apps.', - ], - {withoutStack: true}, - ); - - function ServerComponent() { - return ReactServer.use(ContextA) + ReactServer.use(ContextB); - } - function Server() { - return ( - - - - ); - } - const stream = ReactServerDOMServer.renderToReadableStream(); - const response = ReactServerDOMClient.createFromReadableStream(stream); - - function Client() { - return use(response); - } - - const container = document.createElement('div'); - const root = ReactDOMClient.createRoot(container); - await act(() => { - // Client uses a different renderer. - // We reset _currentRenderer here to not trigger a warning about multiple - // renderers concurrently using this context - ContextA._currentRenderer = null; - root.render(); - }); - expect(container.innerHTML).toBe('AB'); - }); - it('use(promise) in multiple components', async () => { function Child({prefix}) { return ( diff --git a/packages/react-server/src/ReactFizzHooks.js b/packages/react-server/src/ReactFizzHooks.js index 52ea64f4a5c75..6d87b97e9fc6a 100644 --- a/packages/react-server/src/ReactFizzHooks.js +++ b/packages/react-server/src/ReactFizzHooks.js @@ -40,7 +40,6 @@ import { } from 'shared/ReactFeatureFlags'; import is from 'shared/objectIs'; import { - REACT_SERVER_CONTEXT_TYPE, REACT_CONTEXT_TYPE, REACT_MEMO_CACHE_SENTINEL, } from 'shared/ReactSymbols'; @@ -745,10 +744,7 @@ function use(usable: Usable): T { // This is a thenable. const thenable: Thenable = (usable: any); return unwrapThenable(thenable); - } else if ( - usable.$$typeof === REACT_CONTEXT_TYPE || - usable.$$typeof === REACT_SERVER_CONTEXT_TYPE - ) { + } else if (usable.$$typeof === REACT_CONTEXT_TYPE) { const context: ReactContext = (usable: any); return readContext(context); } diff --git a/packages/react-server/src/ReactFizzNewContext.js b/packages/react-server/src/ReactFizzNewContext.js index a2107b573e152..0a9fe3df4c35e 100644 --- a/packages/react-server/src/ReactFizzNewContext.js +++ b/packages/react-server/src/ReactFizzNewContext.js @@ -9,7 +9,6 @@ import type {ReactContext} from 'shared/ReactTypes'; -import {REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED} from 'shared/ReactSymbols'; import {isPrimaryRenderer} from './ReactFizzConfig'; let rendererSigil; @@ -246,11 +245,7 @@ export function popProvider(context: ReactContext): ContextSnapshot { } if (isPrimaryRenderer) { const value = prevSnapshot.parentValue; - if (value === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED) { - prevSnapshot.context._currentValue = prevSnapshot.context._defaultValue; - } else { - prevSnapshot.context._currentValue = value; - } + prevSnapshot.context._currentValue = value; if (__DEV__) { if ( context._currentRenderer !== undefined && @@ -266,11 +261,7 @@ export function popProvider(context: ReactContext): ContextSnapshot { } } else { const value = prevSnapshot.parentValue; - if (value === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED) { - prevSnapshot.context._currentValue2 = prevSnapshot.context._defaultValue; - } else { - prevSnapshot.context._currentValue2 = value; - } + prevSnapshot.context._currentValue2 = value; if (__DEV__) { if ( context._currentRenderer2 !== undefined && diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index 152b3acc24593..dee3fe5bfcfff 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -129,7 +129,6 @@ import { REACT_MEMO_TYPE, REACT_PROVIDER_TYPE, REACT_CONTEXT_TYPE, - REACT_SERVER_CONTEXT_TYPE, REACT_SCOPE_TYPE, REACT_OFFSCREEN_TYPE, REACT_POSTPONE_TYPE, @@ -2270,10 +2269,7 @@ function renderNodeDestructive( ); } - if ( - maybeUsable.$$typeof === REACT_CONTEXT_TYPE || - maybeUsable.$$typeof === REACT_SERVER_CONTEXT_TYPE - ) { + if (maybeUsable.$$typeof === REACT_CONTEXT_TYPE) { const context: ReactContext = (maybeUsable: any); return renderNodeDestructive( request, diff --git a/packages/react-server/src/ReactFlightHooks.js b/packages/react-server/src/ReactFlightHooks.js index 3042c6008cab7..d8223db133db5 100644 --- a/packages/react-server/src/ReactFlightHooks.js +++ b/packages/react-server/src/ReactFlightHooks.js @@ -9,13 +9,12 @@ import type {Dispatcher} from 'react-reconciler/src/ReactInternalTypes'; import type {Request} from './ReactFlightServer'; -import type {ReactServerContext, Thenable, Usable} from 'shared/ReactTypes'; +import type {Thenable, Usable} from 'shared/ReactTypes'; import type {ThenableState} from './ReactFlightThenable'; import { - REACT_SERVER_CONTEXT_TYPE, REACT_MEMO_CACHE_SENTINEL, + REACT_CONTEXT_TYPE, } from 'shared/ReactSymbols'; -import {readContext as readContextImpl} from './ReactFlightNewContext'; import {createThenableState, trackUsedThenable} from './ReactFlightThenable'; import {isClientReference} from './ReactFlightServerConfig'; @@ -44,29 +43,6 @@ export function getThenableStateAfterSuspending(): null | ThenableState { return state; } -function readContext(context: ReactServerContext): T { - if (__DEV__) { - if (context.$$typeof !== REACT_SERVER_CONTEXT_TYPE) { - if (isClientReference(context)) { - console.error('Cannot read a Client Context from a Server Component.'); - } else { - console.error( - 'Only createServerContext is supported in Server Components.', - ); - } - } - if (currentRequest === null) { - console.error( - 'Context can only be read while React is rendering. ' + - 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + - 'In function components, you can read it directly in the function body, but not ' + - 'inside Hooks like useReducer() or useMemo().', - ); - } - } - return readContextImpl(context); -} - export const HooksDispatcher: Dispatcher = { useMemo(nextCreate: () => T): T { return nextCreate(); @@ -77,8 +53,8 @@ export const HooksDispatcher: Dispatcher = { useDebugValue(): void {}, useDeferredValue: (unsupportedHook: any), useTransition: (unsupportedHook: any), - readContext, - useContext: readContext, + readContext: (unsupportedContext: any), + useContext: (unsupportedContext: any), useReducer: (unsupportedHook: any), useRef: (unsupportedHook: any), useState: (unsupportedHook: any), @@ -111,6 +87,10 @@ function unsupportedRefresh(): void { ); } +function unsupportedContext(): void { + throw new Error('Cannot read a Client Context from a Server Component.'); +} + function useId(): string { if (currentRequest === null) { throw new Error('useId can only be used while React is rendering'); @@ -138,18 +118,22 @@ function use(usable: Usable): T { thenableState = createThenableState(); } return trackUsedThenable(thenableState, thenable, index); - } else if (usable.$$typeof === REACT_SERVER_CONTEXT_TYPE) { - const context: ReactServerContext = (usable: any); - return readContext(context); + } else if (usable.$$typeof === REACT_CONTEXT_TYPE) { + unsupportedContext(); } } - if (__DEV__) { - if (isClientReference(usable)) { - console.error('Cannot use() an already resolved Client Reference.'); + if (isClientReference(usable)) { + if (usable.value != null && usable.value.$$typeof === REACT_CONTEXT_TYPE) { + // Show a more specific message since it's a common mistake. + throw new Error('Cannot read a Client Context from a Server Component.'); + } else { + throw new Error('Cannot use() an already resolved Client Reference.'); } + } else { + throw new Error( + // eslint-disable-next-line react-internal/safe-string-coercion + 'An unsupported type was passed to use(): ' + String(usable), + ); } - - // eslint-disable-next-line react-internal/safe-string-coercion - throw new Error('An unsupported type was passed to use(): ' + String(usable)); } diff --git a/packages/react-server/src/ReactFlightNewContext.js b/packages/react-server/src/ReactFlightNewContext.js deleted file mode 100644 index 6412e7c2c7e8c..0000000000000 --- a/packages/react-server/src/ReactFlightNewContext.js +++ /dev/null @@ -1,269 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type { - ReactServerContext, - ServerContextJSONValue, -} from 'shared/ReactTypes'; - -import {REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED} from 'shared/ReactSymbols'; -import {isPrimaryRenderer} from './ReactFlightServerConfig'; - -let rendererSigil; -if (__DEV__) { - // Use this to detect multiple renderers using the same context - rendererSigil = {}; -} - -// Used to store the parent path of all context overrides in a shared linked list. -// Forming a reverse tree. -type ContextNode = { - parent: null | ContextNode, - depth: number, // Short hand to compute the depth of the tree at this node. - context: ReactServerContext, - parentValue: T, - value: T, -}; - -// The structure of a context snapshot is an implementation of this file. -// Currently, it's implemented as tracking the current active node. -export opaque type ContextSnapshot = null | ContextNode; - -export const rootContextSnapshot: ContextSnapshot = null; - -// We assume that this runtime owns the "current" field on all ReactContext instances. -// This global (actually thread local) state represents what state all those "current", -// fields are currently in. -let currentActiveSnapshot: ContextSnapshot = null; - -function popNode(prev: ContextNode): void { - if (isPrimaryRenderer) { - prev.context._currentValue = prev.parentValue; - } else { - prev.context._currentValue2 = prev.parentValue; - } -} - -function pushNode(next: ContextNode): void { - if (isPrimaryRenderer) { - next.context._currentValue = next.value; - } else { - next.context._currentValue2 = next.value; - } -} - -function popToNearestCommonAncestor( - prev: ContextNode, - next: ContextNode, -): void { - if (prev === next) { - // We've found a shared ancestor. We don't need to pop nor reapply this one or anything above. - } else { - popNode(prev); - const parentPrev = prev.parent; - const parentNext = next.parent; - if (parentPrev === null) { - if (parentNext !== null) { - throw new Error( - 'The stacks must reach the root at the same time. This is a bug in React.', - ); - } - } else { - if (parentNext === null) { - throw new Error( - 'The stacks must reach the root at the same time. This is a bug in React.', - ); - } - - popToNearestCommonAncestor(parentPrev, parentNext); - // On the way back, we push the new ones that weren't common. - pushNode(next); - } - } -} - -function popAllPrevious(prev: ContextNode): void { - popNode(prev); - const parentPrev = prev.parent; - if (parentPrev !== null) { - popAllPrevious(parentPrev); - } -} - -function pushAllNext(next: ContextNode): void { - const parentNext = next.parent; - if (parentNext !== null) { - pushAllNext(parentNext); - } - pushNode(next); -} - -function popPreviousToCommonLevel( - prev: ContextNode, - next: ContextNode, -): void { - popNode(prev); - const parentPrev = prev.parent; - - if (parentPrev === null) { - throw new Error( - 'The depth must equal at least at zero before reaching the root. This is a bug in React.', - ); - } - - if (parentPrev.depth === next.depth) { - // We found the same level. Now we just need to find a shared ancestor. - popToNearestCommonAncestor(parentPrev, next); - } else { - // We must still be deeper. - popPreviousToCommonLevel(parentPrev, next); - } -} - -function popNextToCommonLevel( - prev: ContextNode, - next: ContextNode, -): void { - const parentNext = next.parent; - - if (parentNext === null) { - throw new Error( - 'The depth must equal at least at zero before reaching the root. This is a bug in React.', - ); - } - - if (prev.depth === parentNext.depth) { - // We found the same level. Now we just need to find a shared ancestor. - popToNearestCommonAncestor(prev, parentNext); - } else { - // We must still be deeper. - popNextToCommonLevel(prev, parentNext); - } - pushNode(next); -} - -// Perform context switching to the new snapshot. -// To make it cheap to read many contexts, while not suspending, we make the switch eagerly by -// updating all the context's current values. That way reads, always just read the current value. -// At the cost of updating contexts even if they're never read by this subtree. -export function switchContext(newSnapshot: ContextSnapshot): void { - // The basic algorithm we need to do is to pop back any contexts that are no longer on the stack. - // We also need to update any new contexts that are now on the stack with the deepest value. - // The easiest way to update new contexts is to just reapply them in reverse order from the - // perspective of the backpointers. To avoid allocating a lot when switching, we use the stack - // for that. Therefore this algorithm is recursive. - // 1) First we pop which ever snapshot tree was deepest. Popping old contexts as we go. - // 2) Then we find the nearest common ancestor from there. Popping old contexts as we go. - // 3) Then we reapply new contexts on the way back up the stack. - const prev = currentActiveSnapshot; - const next = newSnapshot; - if (prev !== next) { - if (prev === null) { - // $FlowFixMe[incompatible-call]: This has to be non-null since it's not equal to prev. - pushAllNext(next); - } else if (next === null) { - popAllPrevious(prev); - } else if (prev.depth === next.depth) { - popToNearestCommonAncestor(prev, next); - } else if (prev.depth > next.depth) { - popPreviousToCommonLevel(prev, next); - } else { - popNextToCommonLevel(prev, next); - } - currentActiveSnapshot = next; - } -} - -export function pushProvider( - context: ReactServerContext, - nextValue: T, -): ContextSnapshot { - let prevValue; - if (isPrimaryRenderer) { - prevValue = context._currentValue; - context._currentValue = nextValue; - if (__DEV__) { - if ( - context._currentRenderer !== undefined && - context._currentRenderer !== null && - context._currentRenderer !== rendererSigil - ) { - console.error( - 'Detected multiple renderers concurrently rendering the ' + - 'same context provider. This is currently unsupported.', - ); - } - context._currentRenderer = rendererSigil; - } - } else { - prevValue = context._currentValue2; - context._currentValue2 = nextValue; - if (__DEV__) { - if ( - context._currentRenderer2 !== undefined && - context._currentRenderer2 !== null && - context._currentRenderer2 !== rendererSigil - ) { - console.error( - 'Detected multiple renderers concurrently rendering the ' + - 'same context provider. This is currently unsupported.', - ); - } - context._currentRenderer2 = rendererSigil; - } - } - const prevNode = currentActiveSnapshot; - const newNode: ContextNode = { - parent: prevNode, - depth: prevNode === null ? 0 : prevNode.depth + 1, - context: context, - parentValue: prevValue, - value: nextValue, - }; - currentActiveSnapshot = newNode; - return newNode; -} - -export function popProvider(): ContextSnapshot { - const prevSnapshot = currentActiveSnapshot; - - if (prevSnapshot === null) { - throw new Error( - 'Tried to pop a Context at the root of the app. This is a bug in React.', - ); - } - - if (isPrimaryRenderer) { - const value = prevSnapshot.parentValue; - if (value === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED) { - prevSnapshot.context._currentValue = prevSnapshot.context._defaultValue; - } else { - prevSnapshot.context._currentValue = value; - } - } else { - const value = prevSnapshot.parentValue; - if (value === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED) { - prevSnapshot.context._currentValue2 = prevSnapshot.context._defaultValue; - } else { - prevSnapshot.context._currentValue2 = value; - } - } - return (currentActiveSnapshot = prevSnapshot.parent); -} - -export function getActiveContext(): ContextSnapshot { - return currentActiveSnapshot; -} - -export function readContext(context: ReactServerContext): T { - const value = isPrimaryRenderer - ? context._currentValue - : context._currentValue2; - return value; -} diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index f04642737e167..b0e37e20b507c 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -15,7 +15,6 @@ import { enableBinaryFlight, enablePostpone, enableTaint, - enableServerContext, enableServerComponentKeys, } from 'shared/ReactFeatureFlags'; @@ -46,17 +45,13 @@ import type { HintCode, HintModel, } from './ReactFlightServerConfig'; -import type {ContextSnapshot} from './ReactFlightNewContext'; import type {ThenableState} from './ReactFlightThenable'; import type { - ReactProviderType, - ServerContextJSONValue, Wakeable, Thenable, PendingThenable, FulfilledThenable, RejectedThenable, - ReactServerContext, } from 'shared/ReactTypes'; import type {LazyComponent} from 'react/src/ReactLazy'; @@ -82,13 +77,6 @@ import { resetHooksForRequest, } from './ReactFlightHooks'; import {DefaultCacheDispatcher} from './flight/ReactFlightServerCache'; -import { - pushProvider, - popProvider, - switchContext, - getActiveContext, - rootContextSnapshot, -} from './ReactFlightNewContext'; import { getIteratorFn, @@ -98,7 +86,6 @@ import { REACT_LAZY_TYPE, REACT_MEMO_TYPE, REACT_POSTPONE_TYPE, - REACT_PROVIDER_TYPE, } from 'shared/ReactSymbols'; import { @@ -110,7 +97,6 @@ import { objectName, } from 'shared/ReactSerializationErrors'; -import {getOrCreateServerContext} from 'shared/ReactServerContextRegistry'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import ReactServerSharedInternals from './ReactServerSharedInternals'; import isArray from 'shared/isArray'; @@ -153,7 +139,6 @@ export type ReactClientValue = // subtype, so the receiver can only accept once of these. | React$Element | React$Element & any> - | ReactServerContext | string | boolean | number @@ -184,7 +169,6 @@ type Task = { toJSON: (key: string, value: ReactClientValue) => ReactJSONValue, keyPath: null | string, // parent server component keys implicitSlot: boolean, // true if the root server component of this sequence had a null key - context: ContextSnapshot, thenableState: ThenableState | null, }; @@ -209,7 +193,6 @@ export type Request = { writtenSymbols: Map, writtenClientReferences: Map, writtenServerReferences: Map, number>, - writtenProviders: Map, writtenObjects: WeakMap, // -1 means "seen" but not outlined. identifierPrefix: string, identifierCount: number, @@ -266,7 +249,6 @@ export function createRequest( model: ReactClientValue, bundlerConfig: ClientManifest, onError: void | ((error: mixed) => ?string), - context?: Array<[string, ServerContextJSONValue]>, identifierPrefix?: string, onPostpone: void | ((reason: string) => void), ): Request { @@ -307,7 +289,6 @@ export function createRequest( writtenSymbols: new Map(), writtenClientReferences: new Map(), writtenServerReferences: new Map(), - writtenProviders: new Map(), writtenObjects: new WeakMap(), identifierPrefix: identifierPrefix || '', identifierCount: 1, @@ -316,15 +297,7 @@ export function createRequest( onPostpone: onPostpone === undefined ? defaultPostponeHandler : onPostpone, }; request.pendingChunks++; - const rootContext = createRootContext(context); - const rootTask = createTask( - request, - model, - null, - false, - rootContext, - abortSet, - ); + const rootTask = createTask(request, model, null, false, abortSet); pingedTasks.push(rootTask); return request; } @@ -340,14 +313,6 @@ export function resolveRequest(): null | Request { return null; } -function createRootContext( - reqContext?: Array<[string, ServerContextJSONValue]>, -) { - return importServerContexts(reqContext); -} - -const POP = {}; - function serializeThenable( request: Request, task: Task, @@ -359,7 +324,6 @@ function serializeThenable( null, task.keyPath, // the server component sequence continues through Promise-as-a-child. task.implicitSlot, - task.context, request.abortableTasks, ); @@ -735,33 +699,6 @@ function renderElement( case REACT_MEMO_TYPE: { return renderElement(request, task, type.type, key, ref, props); } - case REACT_PROVIDER_TYPE: { - if (enableServerContext) { - task.context = pushProvider(type._context, props.value); - if (__DEV__) { - const extraKeys = Object.keys(props).filter(value => { - if (value === 'children' || value === 'value') { - return false; - } - return true; - }); - if (extraKeys.length !== 0) { - console.error( - 'ServerContext can only have a value prop and children. Found: %s', - JSON.stringify(extraKeys), - ); - } - } - return renderClientElement( - task, - type, - key, - // Rely on __popProvider being serialized last to pop the provider. - {value: props.value, children: props.children, __pop: POP}, - ); - } - // Fallthrough - } } } throw new Error( @@ -783,17 +720,13 @@ function createTask( model: ReactClientValue, keyPath: null | string, implicitSlot: boolean, - context: ContextSnapshot, abortSet: Set, ): Task { const id = request.nextChunkId++; if (typeof model === 'object' && model !== null) { // If we're about to write this into a new task we can assign it an ID early so that // any other references can refer to the value we're about to write. - if ( - enableServerComponentKeys && - (keyPath !== null || implicitSlot || context !== rootContextSnapshot) - ) { + if (enableServerComponentKeys && (keyPath !== null || implicitSlot)) { // If we're in some kind of context we can't necessarily reuse this object depending // what parent components are used. } else { @@ -806,7 +739,6 @@ function createTask( model, keyPath, implicitSlot, - context, ping: () => pingTask(request, task), toJSON: function ( this: @@ -850,26 +782,6 @@ function createTask( ); } } - - if ( - enableServerContext && - parent[0] === REACT_ELEMENT_TYPE && - parent[1] && - (parent[1]: any).$$typeof === REACT_PROVIDER_TYPE && - parentPropertyName === '3' - ) { - insideContextProps = value; - } else if ( - insideContextProps === parent && - parentPropertyName === 'value' - ) { - isInsideContextValue = true; - } else if ( - insideContextProps === parent && - parentPropertyName === 'children' - ) { - isInsideContextValue = false; - } } return renderModel(request, task, parent, parentPropertyName, value); }, @@ -899,10 +811,6 @@ function serializeSymbolReference(name: string): string { return '$S' + name; } -function serializeProviderReference(name: string): string { - return '$P' + name; -} - function serializeNumber(number: number): string | number { if (Number.isFinite(number)) { if (number === 0 && 1 / number === -Infinity) { @@ -1004,7 +912,6 @@ function outlineModel(request: Request, value: ReactClientValue): number { value, null, // The way we use outlining is for reusing an object. false, // It makes no sense for that use case to be contextual. - rootContextSnapshot, // Therefore we don't pass any contextual information along. request.abortableTasks, ); retryTask(request, newTask); @@ -1124,8 +1031,6 @@ function escapeStringValue(value: string): string { } } -let insideContextProps = null; -let isInsideContextValue = false; let modelRoot: null | ReactClientValue = false; function renderModel( @@ -1169,7 +1074,6 @@ function renderModel( task.model, task.keyPath, task.implicitSlot, - task.context, request.abortableTasks, ); const ping = newTask.ping; @@ -1252,19 +1156,12 @@ function renderModelDestructive( if (typeof value === 'object') { switch ((value: any).$$typeof) { case REACT_ELEMENT_TYPE: { - if (__DEV__) { - if (enableServerContext && isInsideContextValue) { - console.error('React elements are not allowed in ServerContext'); - } - } const writtenObjects = request.writtenObjects; const existingId = writtenObjects.get(value); if (existingId !== undefined) { if ( enableServerComponentKeys && - (task.keyPath !== null || - task.implicitSlot || - task.context !== rootContextSnapshot) + (task.keyPath !== null || task.implicitSlot) ) { // If we're in some kind of context we can't reuse the result of this render or // previous renders of this element. We only reuse elements if they're not wrapped @@ -1341,9 +1238,7 @@ function renderModelDestructive( if (existingId !== undefined) { if ( enableServerComponentKeys && - (task.keyPath !== null || - task.implicitSlot || - task.context !== rootContextSnapshot) + (task.keyPath !== null || task.implicitSlot) ) { // If we're in some kind of context we can't reuse the result of this render or // previous renders of this element. We only reuse Promises if they're not wrapped @@ -1366,29 +1261,6 @@ function renderModelDestructive( return serializePromiseID(promiseId); } - if (enableServerContext) { - if ((value: any).$$typeof === REACT_PROVIDER_TYPE) { - const providerKey = ((value: any): ReactProviderType)._context - ._globalName; - const writtenProviders = request.writtenProviders; - let providerId = writtenProviders.get(providerKey); - if (providerId === undefined) { - request.pendingChunks++; - providerId = request.nextChunkId++; - writtenProviders.set(providerKey, providerId); - emitProviderChunk(request, providerId, providerKey); - } - return serializeByValueID(providerId); - } else if (value === POP) { - task.context = popProvider(); - if (__DEV__) { - insideContextProps = null; - isInsideContextValue = false; - } - return (undefined: any); - } - } - if (existingId !== undefined) { if (modelRoot === value) { // This is the ID we're currently emitting so we need to write it @@ -1752,16 +1624,6 @@ function emitSymbolChunk(request: Request, id: number, name: string): void { request.completedImportChunks.push(processedChunk); } -function emitProviderChunk( - request: Request, - id: number, - contextName: string, -): void { - const contextReference = serializeProviderReference(contextName); - const processedChunk = encodeReferenceChunk(request, id, contextReference); - request.completedRegularChunks.push(processedChunk); -} - function emitModelChunk(request: Request, id: number, json: string): void { const row = id.toString(16) + ':' + json + '\n'; const processedChunk = stringToChunk(row); @@ -1776,8 +1638,6 @@ function retryTask(request: Request, task: Task): void { return; } - const prevContext = getActiveContext(); - switchContext(task.context); try { // Track the root so we know that we have to emit this object even though it // already has an ID. This is needed because we might see this object twice @@ -1848,10 +1708,6 @@ function retryTask(request: Request, task: Task): void { task.status = ERRORED; const digest = logRecoverableError(request, x); emitErrorChunk(request, task.id, digest, x); - } finally { - if (enableServerContext) { - switchContext(prevContext); - } } } @@ -2061,21 +1917,3 @@ export function abort(request: Request, reason: mixed): void { fatalError(request, error); } } - -function importServerContexts( - contexts?: Array<[string, ServerContextJSONValue]>, -) { - if (enableServerContext && contexts) { - const prevContext = getActiveContext(); - switchContext(rootContextSnapshot); - for (let i = 0; i < contexts.length; i++) { - const [name, value] = contexts[i]; - const context = getOrCreateServerContext(name); - pushProvider(context, value); - } - const importedContext = getActiveContext(); - switchContext(prevContext); - return importedContext; - } - return rootContextSnapshot; -} diff --git a/packages/react/index.experimental.js b/packages/react/index.experimental.js index c35fd1bd55157..dcb695e438a19 100644 --- a/packages/react/index.experimental.js +++ b/packages/react/index.experimental.js @@ -22,7 +22,6 @@ export { createElement, createFactory, createRef, - createServerContext, use, forwardRef, isValidElement, diff --git a/packages/react/index.js b/packages/react/index.js index 70f61f58e070b..ac3b45c3a7ca8 100644 --- a/packages/react/index.js +++ b/packages/react/index.js @@ -43,7 +43,6 @@ export { createElement, createFactory, createRef, - createServerContext, use, forwardRef, isValidElement, diff --git a/packages/react/src/ReactClient.js b/packages/react/src/ReactClient.js index b6257102485d8..85a9c1d692696 100644 --- a/packages/react/src/ReactClient.js +++ b/packages/react/src/ReactClient.js @@ -62,7 +62,6 @@ import { useOptimistic, } from './ReactHooks'; -import {createServerContext} from './ReactServerContext'; import ReactSharedInternals from './ReactSharedInternalsClient'; import {startTransition} from './ReactStartTransition'; import {act} from './ReactAct'; @@ -81,7 +80,6 @@ export { Component, PureComponent, createContext, - createServerContext, forwardRef, lazy, memo, diff --git a/packages/react/src/ReactContext.js b/packages/react/src/ReactContext.js index d3a05fa94bdba..90e73ec46d065 100644 --- a/packages/react/src/ReactContext.js +++ b/packages/react/src/ReactContext.js @@ -31,10 +31,6 @@ export function createContext(defaultValue: T): ReactContext { // These are circular Provider: (null: any), Consumer: (null: any), - - // Add these to use same hidden class in VM as ServerContext - _defaultValue: (null: any), - _globalName: (null: any), }; context.Provider = { diff --git a/packages/react/src/ReactServer.experimental.js b/packages/react/src/ReactServer.experimental.js index 6b6003385c8c1..159391a28b262 100644 --- a/packages/react/src/ReactServer.experimental.js +++ b/packages/react/src/ReactServer.experimental.js @@ -24,12 +24,10 @@ import { } from 'shared/ReactSymbols'; import {cloneElement, createElement, isValidElement} from './ReactElement'; import {createRef} from './ReactCreateRef'; -import {createServerContext} from './ReactServerContext'; import { use, useId, useCallback, - useContext, useDebugValue, useMemo, getCacheSignal, @@ -66,7 +64,6 @@ export { cloneElement, createElement, createRef, - createServerContext, use, forwardRef, isValidElement, @@ -81,7 +78,6 @@ export { postpone as unstable_postpone, useId, useCallback, - useContext, useDebugValue, useMemo, version, diff --git a/packages/react/src/ReactServer.js b/packages/react/src/ReactServer.js index 7912562a58659..9715e0d94f8e1 100644 --- a/packages/react/src/ReactServer.js +++ b/packages/react/src/ReactServer.js @@ -23,15 +23,7 @@ import { } from 'shared/ReactSymbols'; import {cloneElement, createElement, isValidElement} from './ReactElement'; import {createRef} from './ReactCreateRef'; -import {createServerContext} from './ReactServerContext'; -import { - use, - useId, - useCallback, - useContext, - useDebugValue, - useMemo, -} from './ReactHooks'; +import {use, useId, useCallback, useDebugValue, useMemo} from './ReactHooks'; import {forwardRef} from './ReactForwardRef'; import {lazy} from './ReactLazy'; import {memo} from './ReactMemo'; @@ -56,7 +48,6 @@ export { cloneElement, createElement, createRef, - createServerContext, use, forwardRef, isValidElement, @@ -66,7 +57,6 @@ export { startTransition, useId, useCallback, - useContext, useDebugValue, useMemo, version, diff --git a/packages/react/src/ReactServerContext.js b/packages/react/src/ReactServerContext.js deleted file mode 100644 index e2ed9bea7d0d4..0000000000000 --- a/packages/react/src/ReactServerContext.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import { - REACT_PROVIDER_TYPE, - REACT_SERVER_CONTEXT_TYPE, - REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED, -} from 'shared/ReactSymbols'; - -import type { - ReactServerContext, - ServerContextJSONValue, -} from 'shared/ReactTypes'; - -import {enableServerContext} from 'shared/ReactFeatureFlags'; -import {ContextRegistry} from './ReactServerContextRegistry'; - -export function createServerContext( - globalName: string, - defaultValue: T, -): ReactServerContext { - if (!enableServerContext) { - throw new Error('Not implemented.'); - } - if (__DEV__) { - console.error( - 'Server Context is deprecated and will soon be removed. ' + - 'It was never documented and we have found it not to be useful ' + - 'enough to warrant the downside it imposes on all apps.', - ); - } - let wasDefined = true; - if (!ContextRegistry[globalName]) { - wasDefined = false; - const context: ReactServerContext = { - $$typeof: REACT_SERVER_CONTEXT_TYPE, - - // As a workaround to support multiple concurrent renderers, we categorize - // some renderers as primary and others as secondary. We only expect - // there to be two concurrent renderers at most: React Native (primary) and - // Fabric (secondary); React DOM (primary) and React ART (secondary). - // Secondary renderers store their context values on separate fields. - _currentValue: defaultValue, - _currentValue2: defaultValue, - - _defaultValue: defaultValue, - - // Used to track how many concurrent renderers this context currently - // supports within in a single renderer. Such as parallel server rendering. - _threadCount: 0, - // These are circular - Provider: (null: any), - Consumer: (null: any), - _globalName: globalName, - }; - - context.Provider = { - $$typeof: REACT_PROVIDER_TYPE, - _context: context, - }; - - if (__DEV__) { - let hasWarnedAboutUsingConsumer; - context._currentRenderer = null; - context._currentRenderer2 = null; - Object.defineProperties( - context, - ({ - Consumer: { - get() { - if (!hasWarnedAboutUsingConsumer) { - console.error( - 'Consumer pattern is not supported by ReactServerContext', - ); - hasWarnedAboutUsingConsumer = true; - } - return null; - }, - }, - }: any), - ); - } - ContextRegistry[globalName] = context; - } - - const context = ContextRegistry[globalName]; - if (context._defaultValue === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED) { - context._defaultValue = defaultValue; - if ( - context._currentValue === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED - ) { - context._currentValue = defaultValue; - } - if ( - context._currentValue2 === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED - ) { - context._currentValue2 = defaultValue; - } - } else if (wasDefined) { - throw new Error(`ServerContext: ${globalName} already defined`); - } - return context; -} diff --git a/packages/react/src/ReactServerContextRegistry.js b/packages/react/src/ReactServerContextRegistry.js deleted file mode 100644 index 5fabf15d251a8..0000000000000 --- a/packages/react/src/ReactServerContextRegistry.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type {ReactServerContext} from 'shared/ReactTypes'; - -export const ContextRegistry: { - [globalName: string]: ReactServerContext, -} = {}; diff --git a/packages/react/src/ReactSharedInternalsClient.js b/packages/react/src/ReactSharedInternalsClient.js index e036841282506..3311a8188b014 100644 --- a/packages/react/src/ReactSharedInternalsClient.js +++ b/packages/react/src/ReactSharedInternalsClient.js @@ -11,8 +11,6 @@ import ReactCurrentBatchConfig from './ReactCurrentBatchConfig'; import ReactCurrentActQueue from './ReactCurrentActQueue'; import ReactCurrentOwner from './ReactCurrentOwner'; import ReactDebugCurrentFrame from './ReactDebugCurrentFrame'; -import {enableServerContext} from 'shared/ReactFeatureFlags'; -import {ContextRegistry} from './ReactServerContextRegistry'; const ReactSharedInternals = { ReactCurrentDispatcher, @@ -26,8 +24,4 @@ if (__DEV__) { ReactSharedInternals.ReactCurrentActQueue = ReactCurrentActQueue; } -if (enableServerContext) { - ReactSharedInternals.ContextRegistry = ContextRegistry; -} - export default ReactSharedInternals; diff --git a/packages/react/src/ReactSharedInternalsServer.js b/packages/react/src/ReactSharedInternalsServer.js index 7902104681dc1..64a85be5e266e 100644 --- a/packages/react/src/ReactSharedInternalsServer.js +++ b/packages/react/src/ReactSharedInternalsServer.js @@ -8,8 +8,6 @@ import ReactCurrentDispatcher from './ReactCurrentDispatcher'; import ReactCurrentOwner from './ReactCurrentOwner'; import ReactDebugCurrentFrame from './ReactDebugCurrentFrame'; -import {enableServerContext} from 'shared/ReactFeatureFlags'; -import {ContextRegistry} from './ReactServerContextRegistry'; const ReactSharedInternals = { ReactCurrentDispatcher, @@ -20,8 +18,4 @@ if (__DEV__) { ReactSharedInternals.ReactDebugCurrentFrame = ReactDebugCurrentFrame; } -if (enableServerContext) { - ReactSharedInternals.ContextRegistry = ContextRegistry; -} - export default ReactSharedInternals; diff --git a/packages/react/src/forks/ReactSharedInternalsClient.umd.js b/packages/react/src/forks/ReactSharedInternalsClient.umd.js index 84d4356319853..fe8f6d677f905 100644 --- a/packages/react/src/forks/ReactSharedInternalsClient.umd.js +++ b/packages/react/src/forks/ReactSharedInternalsClient.umd.js @@ -12,8 +12,6 @@ import ReactCurrentActQueue from '../ReactCurrentActQueue'; import ReactCurrentOwner from '../ReactCurrentOwner'; import ReactDebugCurrentFrame from '../ReactDebugCurrentFrame'; import ReactCurrentBatchConfig from '../ReactCurrentBatchConfig'; -import {enableServerContext} from 'shared/ReactFeatureFlags'; -import {ContextRegistry} from '../ReactServerContextRegistry'; const ReactSharedInternalsClient = { ReactCurrentDispatcher, @@ -34,8 +32,4 @@ if (__DEV__) { ReactSharedInternalsClient.ReactDebugCurrentFrame = ReactDebugCurrentFrame; } -if (enableServerContext) { - ReactSharedInternalsClient.ContextRegistry = ContextRegistry; -} - export default ReactSharedInternalsClient; diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 332e7f7bdff27..4540952129a46 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -240,8 +240,6 @@ export const enableAsyncDebugInfo = __EXPERIMENTAL__; // Track which Fiber(s) schedule render work. export const enableUpdaterTracking = __PROFILE__; -export const enableServerContext = __EXPERIMENTAL__; - // Internal only. export const enableGetInspectorDataForInstanceInProduction = false; diff --git a/packages/shared/ReactServerContextRegistry.js b/packages/shared/ReactServerContextRegistry.js deleted file mode 100644 index f5bbbae626766..0000000000000 --- a/packages/shared/ReactServerContextRegistry.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - */ - -import type {ReactServerContext} from 'shared/ReactTypes'; - -import { - REACT_PROVIDER_TYPE, - REACT_SERVER_CONTEXT_TYPE, - REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED, -} from 'shared/ReactSymbols'; - -import ReactSharedInternals from 'shared/ReactSharedInternals'; - -const ContextRegistry = ReactSharedInternals.ContextRegistry; - -export function getOrCreateServerContext( - globalName: string, -): ReactServerContext { - if (!ContextRegistry[globalName]) { - const context: ReactServerContext = { - $$typeof: REACT_SERVER_CONTEXT_TYPE, - - // As a workaround to support multiple concurrent renderers, we categorize - // some renderers as primary and others as secondary. We only expect - // there to be two concurrent renderers at most: React Native (primary) and - // Fabric (secondary); React DOM (primary) and React ART (secondary). - // Secondary renderers store their context values on separate fields. - _currentValue: REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED, - _currentValue2: REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED, - - _defaultValue: REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED, - - // Used to track how many concurrent renderers this context currently - // supports within in a single renderer. Such as parallel server rendering. - _threadCount: 0, - // These are circular - Provider: (null: any), - Consumer: (null: any), - _globalName: globalName, - }; - - context.Provider = { - $$typeof: REACT_PROVIDER_TYPE, - _context: context, - }; - - if (__DEV__) { - let hasWarnedAboutUsingConsumer; - context._currentRenderer = null; - context._currentRenderer2 = null; - Object.defineProperties( - context, - ({ - Consumer: { - get() { - if (!hasWarnedAboutUsingConsumer) { - console.error( - 'Consumer pattern is not supported by ReactServerContext', - ); - hasWarnedAboutUsingConsumer = true; - } - return null; - }, - }, - }: any), - ); - } - ContextRegistry[globalName] = context; - } - return ContextRegistry[globalName]; -} diff --git a/packages/shared/ReactSymbols.js b/packages/shared/ReactSymbols.js index 76df61b393aaf..133a84953ea63 100644 --- a/packages/shared/ReactSymbols.js +++ b/packages/shared/ReactSymbols.js @@ -19,9 +19,6 @@ export const REACT_STRICT_MODE_TYPE: symbol = Symbol.for('react.strict_mode'); export const REACT_PROFILER_TYPE: symbol = Symbol.for('react.profiler'); export const REACT_PROVIDER_TYPE: symbol = Symbol.for('react.provider'); export const REACT_CONTEXT_TYPE: symbol = Symbol.for('react.context'); -export const REACT_SERVER_CONTEXT_TYPE: symbol = Symbol.for( - 'react.server_context', -); export const REACT_FORWARD_REF_TYPE: symbol = Symbol.for('react.forward_ref'); export const REACT_SUSPENSE_TYPE: symbol = Symbol.for('react.suspense'); export const REACT_SUSPENSE_LIST_TYPE: symbol = Symbol.for( @@ -41,9 +38,6 @@ export const REACT_CACHE_TYPE: symbol = Symbol.for('react.cache'); export const REACT_TRACING_MARKER_TYPE: symbol = Symbol.for( 'react.tracing_marker', ); -export const REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED: symbol = Symbol.for( - 'react.default_value', -); export const REACT_MEMO_CACHE_SENTINEL: symbol = Symbol.for( 'react.memo_cache_sentinel', diff --git a/packages/shared/ReactTypes.js b/packages/shared/ReactTypes.js index c4e790ce5d9ee..1fe711b779bf3 100644 --- a/packages/shared/ReactTypes.js +++ b/packages/shared/ReactTypes.js @@ -62,22 +62,8 @@ export type ReactContext = { // This value may be added by application code // to improve DEV tooling display names displayName?: string, - - // only used by ServerContext - _defaultValue: T, - _globalName: string, }; -export type ServerContextJSONValue = - | string - | boolean - | number - | null - | $ReadOnlyArray - | {+[key: string]: ServerContextJSONValue}; - -export type ReactServerContext = ReactContext; - export type ReactPortal = { $$typeof: symbol | number, key: null | string, diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 2b314b6ff2a07..3557296c3c753 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -80,7 +80,6 @@ export const allowConcurrentByDefault = true; export const enableCustomElementPropertySupport = false; export const consoleManagedByDevToolsDuringStrictMode = false; -export const enableServerContext = false; export const enableTransitionTracing = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 9bf741d74a278..7327cc0715eaf 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -66,7 +66,6 @@ export const allowConcurrentByDefault = false; export const enableCustomElementPropertySupport = false; export const consoleManagedByDevToolsDuringStrictMode = false; -export const enableServerContext = false; export const enableTransitionTracing = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 3dcf66f535a9c..84520a9523064 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -66,7 +66,6 @@ export const allowConcurrentByDefault = false; export const enableCustomElementPropertySupport = false; export const consoleManagedByDevToolsDuringStrictMode = false; -export const enableServerContext = false; export const enableTransitionTracing = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index a0eaf1f80966d..0d71df9d1ac6e 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -64,7 +64,6 @@ export const enableUnifiedSyncLane = true; export const allowConcurrentByDefault = true; export const consoleManagedByDevToolsDuringStrictMode = false; -export const enableServerContext = false; export const enableTransitionTracing = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index e97d010255afa..ad6f368f491f4 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -66,7 +66,6 @@ export const allowConcurrentByDefault = true; export const enableCustomElementPropertySupport = false; export const consoleManagedByDevToolsDuringStrictMode = false; -export const enableServerContext = false; export const enableTransitionTracing = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index f573a75b5c588..594e2cba49852 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -100,7 +100,6 @@ export const disableTextareaChildren = __EXPERIMENTAL__; export const allowConcurrentByDefault = true; export const consoleManagedByDevToolsDuringStrictMode = true; -export const enableServerContext = false; export const useModernStrictMode = false; export const enableFizzExternalRuntime = true; diff --git a/packages/shared/getComponentNameFromType.js b/packages/shared/getComponentNameFromType.js index 7fe6e49702ad9..310d4adc595dc 100644 --- a/packages/shared/getComponentNameFromType.js +++ b/packages/shared/getComponentNameFromType.js @@ -24,14 +24,9 @@ import { REACT_LAZY_TYPE, REACT_CACHE_TYPE, REACT_TRACING_MARKER_TYPE, - REACT_SERVER_CONTEXT_TYPE, } from 'shared/ReactSymbols'; -import { - enableServerContext, - enableTransitionTracing, - enableCache, -} from './ReactFeatureFlags'; +import {enableTransitionTracing, enableCache} from './ReactFeatureFlags'; // Keep in sync with react-reconciler/getComponentNameFromFiber function getWrappedName( @@ -127,11 +122,6 @@ export default function getComponentNameFromType(type: mixed): string | null { return null; } } - case REACT_SERVER_CONTEXT_TYPE: - if (enableServerContext) { - const context2 = ((type: any): ReactContext); - return (context2.displayName || context2._globalName) + '.Provider'; - } } } return null; diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index ad5d3ebaf3f5e..11451f2b62316 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -486,5 +486,7 @@ "498": "Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.", "499": "Only plain objects, and a few built-ins, can be passed to Server Actions. Classes or null prototypes are not supported.", "500": "React expected a headers state to exist when emitEarlyPreloads was called but did not find it. This suggests emitEarlyPreloads was called more than once per request. This is a bug in React.", - "501": "The render was aborted with postpone when the shell is incomplete. Reason: %s" + "501": "The render was aborted with postpone when the shell is incomplete. Reason: %s", + "502": "Cannot read a Client Context from a Server Component.", + "503": "Cannot use() an already resolved Client Reference." }