Skip to content

Commit

Permalink
[react-dom] move all client code to react-dom/client (#28271)
Browse files Browse the repository at this point in the history
This PR reorganizes the `react-dom` entrypoint to only pull in code that
is environment agnostic. Previously if you required anything from this
entrypoint in any environment the entire client reconciler was loaded.
In a prior release we added a server rendering stub which you could
alias in server environments to omit this unecessary code. After landing
this change this entrypoint should not load any environment specific
code.

While a few APIs are truly client (browser) only such as createRoot and
hydrateRoot many of the APIs you import from this package are only
useful in the browser but could concievably be imported in shared code
(components running in Fizz or shared components as part of an RSC app).
To avoid making these require opting into the client bundle we are
keeping them in the `react-dom` entrypoint and changing their
implementation so that in environments where they are not particularly
useful they do something benign and expected.

#### Removed APIs
The following APIs are being removed in the next major. Largely they
have all been deprecated already and are part of legacy rendering modes
where concurrent features of React are not available
* `render`
* `hydrate`
* `findDOMNode`
* `unmountComponentAtNode`
* `unstable_createEventHandle`
* `unstable_renderSubtreeIntoContainer`
* `unstable_runWithPrioirty`

#### moved Client APIs
These APIs were available on both `react-dom` (with a warning) and
`react-dom/client`. After this change they are only available on
`react-dom/client`
* `createRoot`
* `hydrateRoot`

#### retained APIs
These APIs still exist on the `react-dom` entrypoint but have normalized
behavior depending on which renderers are currently in scope
* `flushSync`: will execute the function (if provided) inside the
flushSync implemention of FlightServer, Fizz, and Fiber DOM renderers.
* `unstable_batchedUpdates`: This is a noop in concurrent mode because
it is now the only supported behavior because there is no legacy
rendering mode
* `createPortal`: This just produces an object. It can be called from
anywhere but since you will probably not have a handle on a DOM node to
pass to it it will likely warn in environments other than the browser
* preloading APIS such as `preload`: These methods will execute the
preload across all renderers currently in scope. Since we resolve the
Request object on the server using AsyncLocalStorage or the current
function stack in practice only one renderer should act upon the
preload.

In addition to these changes the server rendering stub now just rexports
everything from `react-dom`. In a future minor we will add a warning
when using the stub and in the next major we will remove the stub
altogether

DiffTrain build for commit cb15184.
  • Loading branch information
gnoff committed Apr 24, 2024
1 parent 70ab314 commit ef8407b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<eb0bcf528c3de17c6744b81c980f6aec>>
* @generated SignedSource<<901259dbb520cffda8ebd0f1c24b61d7>>
*/

'use strict';
Expand Down Expand Up @@ -8673,44 +8673,31 @@ function updateMemo(nextCreate, deps) {

function mountDeferredValue(value, initialValue) {
var hook = mountWorkInProgressHook();
return mountDeferredValueImpl(hook, value, initialValue);
return mountDeferredValueImpl(hook, value);
}

function updateDeferredValue(value, initialValue) {
var hook = updateWorkInProgressHook();
var resolvedCurrentHook = currentHook;
var prevValue = resolvedCurrentHook.memoizedState;
return updateDeferredValueImpl(hook, prevValue, value, initialValue);
return updateDeferredValueImpl(hook, prevValue, value);
}

function rerenderDeferredValue(value, initialValue) {
var hook = updateWorkInProgressHook();

if (currentHook === null) {
// This is a rerender during a mount.
return mountDeferredValueImpl(hook, value, initialValue);
return mountDeferredValueImpl(hook, value);
} else {
// This is a rerender during an update.
var prevValue = currentHook.memoizedState;
return updateDeferredValueImpl(hook, prevValue, value, initialValue);
return updateDeferredValueImpl(hook, prevValue, value);
}
}

function mountDeferredValueImpl(hook, value, initialValue) {
if (// When `initialValue` is provided, we defer the initial render even if the
// current render is not synchronous.
initialValue !== undefined && // However, to avoid waterfalls, we do not defer if this render
// was itself spawned by an earlier useDeferredValue. Check if DeferredLane
// is part of the render lanes.
!includesSomeLane(renderLanes, DeferredLane)) {
// Render with the initial value
hook.memoizedState = initialValue; // Schedule a deferred render to switch to the final value.

var deferredLane = requestDeferredLane();
currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
markSkippedUpdateLanes(deferredLane);
return initialValue;
} else {
{
hook.memoizedState = value;
return value;
}
Expand All @@ -8727,7 +8714,7 @@ function updateDeferredValueImpl(hook, prevValue, value, initialValue) {
if (isCurrentTreeHidden()) {
// Revealing a prerendered tree is considered the same as mounting new
// one, so we reuse the "mount" path in this case.
var resultValue = mountDeferredValueImpl(hook, value, initialValue); // Unlike during an actual mount, we need to mark this as an update if
var resultValue = mountDeferredValueImpl(hook, value); // Unlike during an actual mount, we need to mark this as an update if
// the value changed.

if (!objectIs(resultValue, prevValue)) {
Expand Down Expand Up @@ -9332,7 +9319,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
useDeferredValue: function (value, initialValue) {
currentHookNameInDev = 'useDeferredValue';
mountHookTypesDev();
return mountDeferredValue(value, initialValue);
return mountDeferredValue(value);
},
useTransition: function () {
currentHookNameInDev = 'useTransition';
Expand Down Expand Up @@ -9471,7 +9458,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
useDeferredValue: function (value, initialValue) {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return mountDeferredValue(value, initialValue);
return mountDeferredValue(value);
},
useTransition: function () {
currentHookNameInDev = 'useTransition';
Expand Down Expand Up @@ -9611,7 +9598,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
useDeferredValue: function (value, initialValue) {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return updateDeferredValue(value, initialValue);
return updateDeferredValue(value);
},
useTransition: function () {
currentHookNameInDev = 'useTransition';
Expand Down Expand Up @@ -9751,7 +9738,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
useDeferredValue: function (value, initialValue) {
currentHookNameInDev = 'useDeferredValue';
updateHookTypesDev();
return rerenderDeferredValue(value, initialValue);
return rerenderDeferredValue(value);
},
useTransition: function () {
currentHookNameInDev = 'useTransition';
Expand Down Expand Up @@ -9907,7 +9894,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
mountHookTypesDev();
return mountDeferredValue(value, initialValue);
return mountDeferredValue(value);
},
useTransition: function () {
currentHookNameInDev = 'useTransition';
Expand Down Expand Up @@ -10071,7 +10058,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
updateHookTypesDev();
return updateDeferredValue(value, initialValue);
return updateDeferredValue(value);
},
useTransition: function () {
currentHookNameInDev = 'useTransition';
Expand Down Expand Up @@ -10235,7 +10222,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
currentHookNameInDev = 'useDeferredValue';
warnInvalidHookAccess();
updateHookTypesDev();
return rerenderDeferredValue(value, initialValue);
return rerenderDeferredValue(value);
},
useTransition: function () {
currentHookNameInDev = 'useTransition';
Expand Down Expand Up @@ -22996,7 +22983,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}

var ReactVersion = '19.0.0-canary-d851d267';
var ReactVersion = '19.0.0-canary-5e828dec';

/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b039be627dd7403d7d2f63a48c8d263d955ce456
cb151849e13f46ec64570519cb93d5939fb60cab

0 comments on commit ef8407b

Please sign in to comment.