Skip to content

Commit

Permalink
Add isRootDehydrated function
Browse files Browse the repository at this point in the history
Currently this does nothing except read a boolean field, but I'm about
to change this logic.

Since this is accessed by React DOM, too, I put the function in a
separate module that can be deep imported. Previously, it was accessing
the FiberRoot directly. The reason it's a separate module is to break a
circular dependency between React DOM and the reconciler.
  • Loading branch information
acdlite committed Mar 12, 2022
1 parent c8e4789 commit 83b941a
Show file tree
Hide file tree
Showing 13 changed files with 45 additions and 16 deletions.
3 changes: 2 additions & 1 deletion packages/react-dom/src/events/ReactDOMEventListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
setCurrentUpdatePriority,
} from 'react-reconciler/src/ReactEventPriorities';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {isRootDehydrated} from 'react-reconciler/src/ReactFiberShellHydration';

const {ReactCurrentBatchConfig} = ReactSharedInternals;

Expand Down Expand Up @@ -386,7 +387,7 @@ export function findInstanceBlockingEvent(
targetInst = null;
} else if (tag === HostRoot) {
const root: FiberRoot = nearestMounted.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
// If this happens during a replay something went wrong and it might block
// the whole system.
return getContainerFromFiber(nearestMounted);
Expand Down
3 changes: 2 additions & 1 deletion packages/react-dom/src/events/ReactDOMEventReplaying.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
} from '../client/ReactDOMComponentTree';
import {HostRoot, SuspenseComponent} from 'react-reconciler/src/ReactWorkTags';
import {isHigherEventPriority} from 'react-reconciler/src/ReactEventPriorities';
import {isRootDehydrated} from 'react-reconciler/src/ReactFiberShellHydration';

let _attemptSynchronousHydration: (fiber: Object) => void;

Expand Down Expand Up @@ -414,7 +415,7 @@ function attemptExplicitHydrationTarget(
}
} else if (tag === HostRoot) {
const root: FiberRoot = nearestMounted.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
queuedTarget.blockedOn = getContainerFromFiber(nearestMounted);
// We don't currently have a way to increase the priority of
// a root other than sync.
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ import {
createOffscreenHostContainerFiber,
isSimpleFunctionComponent,
} from './ReactFiber.new';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {
retryDehydratedSuspenseBoundary,
scheduleUpdateOnFiber,
Expand Down Expand Up @@ -1351,7 +1352,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
resetHydrationState();
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
}
if (root.isDehydrated && enterHydrationState(workInProgress)) {
if (isRootDehydrated(root) && enterHydrationState(workInProgress)) {
// If we don't have any current children this might be the first pass.
// We always try to hydrate. If this isn't a hydration pass there won't
// be any children to hydrate which is effectively the same thing as
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberBeginWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ import {
createOffscreenHostContainerFiber,
isSimpleFunctionComponent,
} from './ReactFiber.old';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {
retryDehydratedSuspenseBoundary,
scheduleUpdateOnFiber,
Expand Down Expand Up @@ -1351,7 +1352,7 @@ function updateHostRoot(current, workInProgress, renderLanes) {
resetHydrationState();
return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
}
if (root.isDehydrated && enterHydrationState(workInProgress)) {
if (isRootDehydrated(root) && enterHydrationState(workInProgress)) {
// If we don't have any current children this might be the first pass.
// We always try to hydrate. If this isn't a hydration pass there won't
// be any children to hydrate which is effectively the same thing as
Expand Down
5 changes: 3 additions & 2 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import {
Visibility,
} from './ReactFiberFlags';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {
resetCurrentFiber as resetCurrentDebugFiberInDEV,
setCurrentFiber as setCurrentDebugFiberInDEV,
Expand Down Expand Up @@ -1878,7 +1879,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
case HostRoot: {
if (supportsHydration) {
const root: FiberRoot = finishedWork.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
// We've just hydrated. No need to hydrate again.
root.isDehydrated = false;
commitHydratedContainer(root.containerInfo);
Expand Down Expand Up @@ -1986,7 +1987,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
case HostRoot: {
if (supportsHydration) {
const root: FiberRoot = finishedWork.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
// We've just hydrated. No need to hydrate again.
root.isDehydrated = false;
commitHydratedContainer(root.containerInfo);
Expand Down
5 changes: 3 additions & 2 deletions packages/react-reconciler/src/ReactFiberCommitWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import {
Visibility,
} from './ReactFiberFlags';
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {
resetCurrentFiber as resetCurrentDebugFiberInDEV,
setCurrentFiber as setCurrentDebugFiberInDEV,
Expand Down Expand Up @@ -1878,7 +1879,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
case HostRoot: {
if (supportsHydration) {
const root: FiberRoot = finishedWork.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
// We've just hydrated. No need to hydrate again.
root.isDehydrated = false;
commitHydratedContainer(root.containerInfo);
Expand Down Expand Up @@ -1986,7 +1987,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
case HostRoot: {
if (supportsHydration) {
const root: FiberRoot = finishedWork.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
// We've just hydrated. No need to hydrate again.
root.isDehydrated = false;
commitHydratedContainer(root.containerInfo);
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberCompleteWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ import {
includesSomeLane,
mergeLanes,
} from './ReactFiberLane.new';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {resetChildFibers} from './ReactChildFiber.new';
import {createScopeInstance} from './ReactFiberScope.new';
import {transferActualDuration} from './ReactProfilerTimer.new';
Expand Down Expand Up @@ -890,7 +891,7 @@ function completeWork(
// If we hydrated, then we'll need to schedule an update for
// the commit side-effects on the root.
markUpdate(workInProgress);
} else if (!fiberRoot.isDehydrated) {
} else if (!isRootDehydrated(fiberRoot)) {
// Schedule an effect to clear this container at the start of the next commit.
// This handles the case of React rendering into a container with previous children.
// It's also safe to do for updates too, because current.child would only be null
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberCompleteWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ import {
includesSomeLane,
mergeLanes,
} from './ReactFiberLane.old';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {resetChildFibers} from './ReactChildFiber.old';
import {createScopeInstance} from './ReactFiberScope.old';
import {transferActualDuration} from './ReactProfilerTimer.old';
Expand Down Expand Up @@ -890,7 +891,7 @@ function completeWork(
// If we hydrated, then we'll need to schedule an update for
// the commit side-effects on the root.
markUpdate(workInProgress);
} else if (!fiberRoot.isDehydrated) {
} else if (!isRootDehydrated(fiberRoot)) {
// Schedule an effect to clear this container at the start of the next commit.
// This handles the case of React rendering into a container with previous children.
// It's also safe to do for updates too, because current.child would only be null
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberReconciler.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
isContextProvider as isLegacyContextProvider,
} from './ReactFiberContext.new';
import {createFiberRoot} from './ReactFiberRoot.new';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {
injectInternals,
markRenderScheduled,
Expand Down Expand Up @@ -411,7 +412,7 @@ export function attemptSynchronousHydration(fiber: Fiber): void {
switch (fiber.tag) {
case HostRoot:
const root: FiberRoot = fiber.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
// Flush the first scheduled "update".
const lanes = getHighestPriorityPendingLanes(root);
flushRoot(root, lanes);
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactFiberReconciler.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
isContextProvider as isLegacyContextProvider,
} from './ReactFiberContext.old';
import {createFiberRoot} from './ReactFiberRoot.old';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {
injectInternals,
markRenderScheduled,
Expand Down Expand Up @@ -411,7 +412,7 @@ export function attemptSynchronousHydration(fiber: Fiber): void {
switch (fiber.tag) {
case HostRoot:
const root: FiberRoot = fiber.stateNode;
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
// Flush the first scheduled "update".
const lanes = getHighestPriorityPendingLanes(root);
flushRoot(root, lanes);
Expand Down
17 changes: 17 additions & 0 deletions packages/react-reconciler/src/ReactFiberShellHydration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) Facebook, Inc. and its 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 {FiberRoot} from './ReactInternalTypes';

// This is imported by the event replaying implementation in React DOM. It's
// in a separate file to break a circular dependency between the renderer and
// the reconciler.
export function isRootDehydrated(root: FiberRoot) {
return root.isDehydrated;
}
5 changes: 3 additions & 2 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import {
createWorkInProgress,
assignFiberPropertiesInDEV,
} from './ReactFiber.new';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {NoMode, ProfileMode, ConcurrentMode} from './ReactTypeOfMode';
import {
HostRoot,
Expand Down Expand Up @@ -581,7 +582,7 @@ export function scheduleUpdateOnFiber(
}
}

if (root.isDehydrated && root.tag !== LegacyRoot) {
if (isRootDehydrated(root) && root.tag !== LegacyRoot) {
// This root's shell hasn't hydrated yet. Revert to client rendering.
if (workInProgressRoot === root) {
// If this happened during an interleaved event, interrupt the
Expand Down Expand Up @@ -1016,7 +1017,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
function recoverFromConcurrentError(root, errorRetryLanes) {
// If an error occurred during hydration, discard server response and fall
// back to client side render.
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
root.isDehydrated = false;
if (__DEV__) {
errorHydratingContainer(root.containerInfo);
Expand Down
5 changes: 3 additions & 2 deletions packages/react-reconciler/src/ReactFiberWorkLoop.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import {
createWorkInProgress,
assignFiberPropertiesInDEV,
} from './ReactFiber.old';
import {isRootDehydrated} from './ReactFiberShellHydration';
import {NoMode, ProfileMode, ConcurrentMode} from './ReactTypeOfMode';
import {
HostRoot,
Expand Down Expand Up @@ -581,7 +582,7 @@ export function scheduleUpdateOnFiber(
}
}

if (root.isDehydrated && root.tag !== LegacyRoot) {
if (isRootDehydrated(root) && root.tag !== LegacyRoot) {
// This root's shell hasn't hydrated yet. Revert to client rendering.
if (workInProgressRoot === root) {
// If this happened during an interleaved event, interrupt the
Expand Down Expand Up @@ -1016,7 +1017,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
function recoverFromConcurrentError(root, errorRetryLanes) {
// If an error occurred during hydration, discard server response and fall
// back to client side render.
if (root.isDehydrated) {
if (isRootDehydrated(root)) {
root.isDehydrated = false;
if (__DEV__) {
errorHydratingContainer(root.containerInfo);
Expand Down

0 comments on commit 83b941a

Please sign in to comment.