From 0a21cd303074d4e6327ac1262f43a398cf4229a4 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Tue, 10 May 2022 11:35:56 -0400 Subject: [PATCH 1/3] Only treat updates to lazy as a new mount in legacy mode --- .../src/ReactFiberBeginWork.new.js | 60 +++++++------------ .../src/ReactFiberBeginWork.old.js | 60 +++++++------------ 2 files changed, 40 insertions(+), 80 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index 662ac5bbe59a2..b0315297c21e1 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -1110,16 +1110,8 @@ function updateClassComponent( const instance = workInProgress.stateNode; let shouldUpdate; if (instance === null) { - if (current !== null) { - // A class component without an instance only mounts if it suspended - // inside a non-concurrent tree, in an inconsistent state. We want to - // treat it like a new mount, even though an empty version of it already - // committed. Disconnect the alternate pointers. - current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(current, workInProgress); + // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, Component, nextProps); mountClassInstance(workInProgress, Component, nextProps, renderLanes); @@ -1469,16 +1461,7 @@ function mountLazyComponent( elementType, renderLanes, ) { - if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; const lazyComponent: LazyComponentType = elementType; @@ -1588,16 +1571,7 @@ function mountIncompleteClassComponent( nextProps, renderLanes, ) { - if (_current !== null) { - // An incomplete component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. workInProgress.tag = ClassComponent; @@ -1635,16 +1609,7 @@ function mountIndeterminateComponent( Component, renderLanes, ) { - if (_current !== null) { - // An indeterminate component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; let context; @@ -3376,6 +3341,21 @@ export function checkIfWorkInProgressReceivedUpdate() { return didReceiveUpdate; } +function resetIndeterminatePlacementForLegacyMode(current, workInProgress) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; + // Since this is conceptually a new fiber, schedule a Placement effect + workInProgress.flags |= Placement; + } + } +} + function bailoutOnAlreadyFinishedWork( current: Fiber | null, workInProgress: Fiber, diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index 81815280e07ee..3bd96af6bf04f 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -1110,16 +1110,8 @@ function updateClassComponent( const instance = workInProgress.stateNode; let shouldUpdate; if (instance === null) { - if (current !== null) { - // A class component without an instance only mounts if it suspended - // inside a non-concurrent tree, in an inconsistent state. We want to - // treat it like a new mount, even though an empty version of it already - // committed. Disconnect the alternate pointers. - current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(current, workInProgress); + // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, Component, nextProps); mountClassInstance(workInProgress, Component, nextProps, renderLanes); @@ -1469,16 +1461,7 @@ function mountLazyComponent( elementType, renderLanes, ) { - if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; const lazyComponent: LazyComponentType = elementType; @@ -1588,16 +1571,7 @@ function mountIncompleteClassComponent( nextProps, renderLanes, ) { - if (_current !== null) { - // An incomplete component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. workInProgress.tag = ClassComponent; @@ -1635,16 +1609,7 @@ function mountIndeterminateComponent( Component, renderLanes, ) { - if (_current !== null) { - // An indeterminate component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; - // Since this is conceptually a new fiber, schedule a Placement effect - workInProgress.flags |= Placement; - } + resetIndeterminatePlacementForLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; let context; @@ -3376,6 +3341,21 @@ export function checkIfWorkInProgressReceivedUpdate() { return didReceiveUpdate; } +function resetIndeterminatePlacementForLegacyMode(current, workInProgress) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; + // Since this is conceptually a new fiber, schedule a Placement effect + workInProgress.flags |= Placement; + } + } +} + function bailoutOnAlreadyFinishedWork( current: Fiber | null, workInProgress: Fiber, From 1fc45f3efc5668bab3627884cc464b15288eb522 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Tue, 10 May 2022 14:35:43 -0400 Subject: [PATCH 2/3] Update name and swap current check --- .../src/ReactFiberBeginWork.new.js | 14 +++++++------- .../src/ReactFiberBeginWork.old.js | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index b0315297c21e1..3d797b04d2825 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -1110,7 +1110,7 @@ function updateClassComponent( const instance = workInProgress.stateNode; let shouldUpdate; if (instance === null) { - resetIndeterminatePlacementForLegacyMode(current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, Component, nextProps); @@ -1461,7 +1461,7 @@ function mountLazyComponent( elementType, renderLanes, ) { - resetIndeterminatePlacementForLegacyMode(_current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; const lazyComponent: LazyComponentType = elementType; @@ -1571,7 +1571,7 @@ function mountIncompleteClassComponent( nextProps, renderLanes, ) { - resetIndeterminatePlacementForLegacyMode(_current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. workInProgress.tag = ClassComponent; @@ -1609,7 +1609,7 @@ function mountIndeterminateComponent( Component, renderLanes, ) { - resetIndeterminatePlacementForLegacyMode(_current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; let context; @@ -3341,9 +3341,9 @@ export function checkIfWorkInProgressReceivedUpdate() { return didReceiveUpdate; } -function resetIndeterminatePlacementForLegacyMode(current, workInProgress) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - if (current !== null) { +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + if (current !== null) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed. diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index 3bd96af6bf04f..9917d5607a5e2 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -1110,7 +1110,7 @@ function updateClassComponent( const instance = workInProgress.stateNode; let shouldUpdate; if (instance === null) { - resetIndeterminatePlacementForLegacyMode(current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, Component, nextProps); @@ -1461,7 +1461,7 @@ function mountLazyComponent( elementType, renderLanes, ) { - resetIndeterminatePlacementForLegacyMode(_current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; const lazyComponent: LazyComponentType = elementType; @@ -1571,7 +1571,7 @@ function mountIncompleteClassComponent( nextProps, renderLanes, ) { - resetIndeterminatePlacementForLegacyMode(_current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. workInProgress.tag = ClassComponent; @@ -1609,7 +1609,7 @@ function mountIndeterminateComponent( Component, renderLanes, ) { - resetIndeterminatePlacementForLegacyMode(_current, workInProgress); + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); const props = workInProgress.pendingProps; let context; @@ -3341,9 +3341,9 @@ export function checkIfWorkInProgressReceivedUpdate() { return didReceiveUpdate; } -function resetIndeterminatePlacementForLegacyMode(current, workInProgress) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - if (current !== null) { +function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + if (current !== null) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed. From 127414540610a363af10a1ebde2ebcfd2398db77 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Tue, 10 May 2022 16:47:23 -0400 Subject: [PATCH 3/3] Flip order back --- packages/react-reconciler/src/ReactFiberBeginWork.new.js | 4 ++-- packages/react-reconciler/src/ReactFiberBeginWork.old.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index 3d797b04d2825..9ca86babe3e71 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -3342,8 +3342,8 @@ export function checkIfWorkInProgressReceivedUpdate() { } function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { - if (current !== null) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed. diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index 9917d5607a5e2..32dc0c8e81838 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -3342,8 +3342,8 @@ export function checkIfWorkInProgressReceivedUpdate() { } function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { - if (current !== null) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { // A lazy component only mounts if it suspended inside a non- // concurrent tree, in an inconsistent state. We want to treat it like // a new mount, even though an empty version of it already committed.