diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js index f8b8231f8f40e..e2974586ec6ac 100644 --- a/packages/react-dom/src/events/ReactDOMEventListener.js +++ b/packages/react-dom/src/events/ReactDOMEventListener.js @@ -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; @@ -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); diff --git a/packages/react-dom/src/events/ReactDOMEventReplaying.js b/packages/react-dom/src/events/ReactDOMEventReplaying.js index 744f5dfda9d9b..9de82a99a7be3 100644 --- a/packages/react-dom/src/events/ReactDOMEventReplaying.js +++ b/packages/react-dom/src/events/ReactDOMEventReplaying.js @@ -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; @@ -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. diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index 4bae5d0b7b982..4feff7d260668 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -223,6 +223,7 @@ import { createOffscreenHostContainerFiber, isSimpleFunctionComponent, } from './ReactFiber.new'; +import {isRootDehydrated} from './ReactFiberShellHydration'; import { retryDehydratedSuspenseBoundary, scheduleUpdateOnFiber, @@ -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 diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index 583539dd08b52..bdb53d6b36e5a 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -223,6 +223,7 @@ import { createOffscreenHostContainerFiber, isSimpleFunctionComponent, } from './ReactFiber.old'; +import {isRootDehydrated} from './ReactFiberShellHydration'; import { retryDehydratedSuspenseBoundary, scheduleUpdateOnFiber, @@ -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 diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.new.js b/packages/react-reconciler/src/ReactFiberCommitWork.new.js index 75553555b928d..6f6b59b4ecee6 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.new.js @@ -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, @@ -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); @@ -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); diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.old.js b/packages/react-reconciler/src/ReactFiberCommitWork.old.js index 23e9d6070c9a2..af044c79cada7 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.old.js @@ -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, @@ -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); @@ -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); diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js index 2a44cf94a14aa..e00fdf5850aeb 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js @@ -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'; @@ -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 diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.old.js b/packages/react-reconciler/src/ReactFiberCompleteWork.old.js index f02a20222d0fe..1c47a291caf00 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.old.js @@ -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'; @@ -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 diff --git a/packages/react-reconciler/src/ReactFiberReconciler.new.js b/packages/react-reconciler/src/ReactFiberReconciler.new.js index 67eb7f7b232e5..b814c35cf8350 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.new.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.new.js @@ -48,6 +48,7 @@ import { isContextProvider as isLegacyContextProvider, } from './ReactFiberContext.new'; import {createFiberRoot} from './ReactFiberRoot.new'; +import {isRootDehydrated} from './ReactFiberShellHydration'; import { injectInternals, markRenderScheduled, @@ -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); diff --git a/packages/react-reconciler/src/ReactFiberReconciler.old.js b/packages/react-reconciler/src/ReactFiberReconciler.old.js index 378035e95e661..9665ca44bc52a 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.old.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.old.js @@ -48,6 +48,7 @@ import { isContextProvider as isLegacyContextProvider, } from './ReactFiberContext.old'; import {createFiberRoot} from './ReactFiberRoot.old'; +import {isRootDehydrated} from './ReactFiberShellHydration'; import { injectInternals, markRenderScheduled, @@ -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); diff --git a/packages/react-reconciler/src/ReactFiberShellHydration.js b/packages/react-reconciler/src/ReactFiberShellHydration.js new file mode 100644 index 0000000000000..2f1afde6de969 --- /dev/null +++ b/packages/react-reconciler/src/ReactFiberShellHydration.js @@ -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; +} diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 7223ad7d052b0..caab7a666f655 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -88,6 +88,7 @@ import { createWorkInProgress, assignFiberPropertiesInDEV, } from './ReactFiber.new'; +import {isRootDehydrated} from './ReactFiberShellHydration'; import {NoMode, ProfileMode, ConcurrentMode} from './ReactTypeOfMode'; import { HostRoot, @@ -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 @@ -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); diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index d8bb6b16e29fb..04a324cdc83eb 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -88,6 +88,7 @@ import { createWorkInProgress, assignFiberPropertiesInDEV, } from './ReactFiber.old'; +import {isRootDehydrated} from './ReactFiberShellHydration'; import {NoMode, ProfileMode, ConcurrentMode} from './ReactTypeOfMode'; import { HostRoot, @@ -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 @@ -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);