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."
}