From 30843a17d75922dd9562af183db0b7855b794980 Mon Sep 17 00:00:00 2001 From: Marco Salazar Date: Wed, 8 Dec 2021 10:53:48 -0500 Subject: [PATCH 1/4] avoidThisFallbackFlag --- packages/react-reconciler/src/ReactFiberBeginWork.new.js | 6 +++++- packages/react-reconciler/src/ReactFiberBeginWork.old.js | 6 +++++- packages/react-reconciler/src/ReactFiberCompleteWork.new.js | 4 +++- packages/react-reconciler/src/ReactFiberCompleteWork.old.js | 4 +++- .../react-reconciler/src/ReactFiberSuspenseComponent.new.js | 6 +++++- .../react-reconciler/src/ReactFiberSuspenseComponent.old.js | 6 +++++- .../shared/forks/ReactFeatureFlags.test-renderer.www.js | 2 +- packages/shared/forks/ReactFeatureFlags.testing.www.js | 2 +- packages/shared/forks/ReactFeatureFlags.www.js | 2 +- 9 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index d66bba0dc2ee3..be0e2deb301a9 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -29,6 +29,7 @@ import type { SpawnedCachePool, } from './ReactFiberCacheComponent.new'; import type {UpdateQueue} from './ReactUpdateQueue.new'; +import {enableSuspenseAvoidThisFallback} from 'shared/ReactFeatureFlags'; import checkPropTypes from 'shared/checkPropTypes'; import { @@ -1997,7 +1998,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { // Mark this subtree context as having at least one invisible parent that could // handle the fallback state. // Avoided boundaries are not considered since they cannot handle preferred fallback states. - if (nextProps.unstable_avoidThisFallback !== true) { + if ( + !enableSuspenseAvoidThisFallback || + nextProps.unstable_avoidThisFallback !== true + ) { suspenseContext = addSubtreeSuspenseContext( suspenseContext, InvisibleParentSuspenseContext, diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index 62d51046b3c46..39390243216f9 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -29,6 +29,7 @@ import type { SpawnedCachePool, } from './ReactFiberCacheComponent.old'; import type {UpdateQueue} from './ReactUpdateQueue.old'; +import {enableSuspenseAvoidThisFallback} from 'shared/ReactFeatureFlags'; import checkPropTypes from 'shared/checkPropTypes'; import { @@ -1997,7 +1998,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { // Mark this subtree context as having at least one invisible parent that could // handle the fallback state. // Avoided boundaries are not considered since they cannot handle preferred fallback states. - if (nextProps.unstable_avoidThisFallback !== true) { + if ( + !enableSuspenseAvoidThisFallback || + nextProps.unstable_avoidThisFallback !== true + ) { suspenseContext = addSubtreeSuspenseContext( suspenseContext, InvisibleParentSuspenseContext, diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js index 5805ffe8da769..91c564dd465ba 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js @@ -29,6 +29,7 @@ import type { import type {SuspenseContext} from './ReactFiberSuspenseContext.new'; import type {OffscreenState} from './ReactFiberOffscreenComponent'; import type {Cache, SpawnedCachePool} from './ReactFiberCacheComponent.new'; +import {enableSuspenseAvoidThisFallback} from 'shared/ReactFeatureFlags'; import {resetWorkInProgressVersions as resetMutableSourceWorkInProgressVersions} from './ReactMutableSource.new'; @@ -1154,7 +1155,8 @@ function completeWork( // should be able to immediately restart from within throwException. const hasInvisibleChildContext = current === null && - workInProgress.memoizedProps.unstable_avoidThisFallback !== true; + (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || + !enableSuspenseAvoidThisFallback); if ( hasInvisibleChildContext || hasSuspenseContext( diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.old.js b/packages/react-reconciler/src/ReactFiberCompleteWork.old.js index c5eb5f70f48d6..ea994583cfe8d 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.old.js @@ -29,6 +29,7 @@ import type { import type {SuspenseContext} from './ReactFiberSuspenseContext.old'; import type {OffscreenState} from './ReactFiberOffscreenComponent'; import type {Cache, SpawnedCachePool} from './ReactFiberCacheComponent.old'; +import {enableSuspenseAvoidThisFallback} from 'shared/ReactFeatureFlags'; import {resetWorkInProgressVersions as resetMutableSourceWorkInProgressVersions} from './ReactMutableSource.old'; @@ -1154,7 +1155,8 @@ function completeWork( // should be able to immediately restart from within throwException. const hasInvisibleChildContext = current === null && - workInProgress.memoizedProps.unstable_avoidThisFallback !== true; + (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || + !enableSuspenseAvoidThisFallback); if ( hasInvisibleChildContext || hasSuspenseContext( diff --git a/packages/react-reconciler/src/ReactFiberSuspenseComponent.new.js b/packages/react-reconciler/src/ReactFiberSuspenseComponent.new.js index 9dbaf7fb76efd..54e37a9004d7f 100644 --- a/packages/react-reconciler/src/ReactFiberSuspenseComponent.new.js +++ b/packages/react-reconciler/src/ReactFiberSuspenseComponent.new.js @@ -13,6 +13,7 @@ import type {SuspenseInstance} from './ReactFiberHostConfig'; import type {Lane} from './ReactFiberLane.new'; import type {TreeContext} from './ReactFiberTreeContext.new'; +import {enableSuspenseAvoidThisFallback} from 'shared/ReactFeatureFlags'; import {SuspenseComponent, SuspenseListComponent} from './ReactWorkTags'; import {NoFlags, DidCapture} from './ReactFiberFlags'; import { @@ -81,7 +82,10 @@ export function shouldCaptureSuspense( } const props = workInProgress.memoizedProps; // Regular boundaries always capture. - if (props.unstable_avoidThisFallback !== true) { + if ( + !enableSuspenseAvoidThisFallback || + props.unstable_avoidThisFallback !== true + ) { return true; } // If it's a boundary we should avoid, then we prefer to bubble up to the diff --git a/packages/react-reconciler/src/ReactFiberSuspenseComponent.old.js b/packages/react-reconciler/src/ReactFiberSuspenseComponent.old.js index 726f0ca52005f..95fb1b8c8ab42 100644 --- a/packages/react-reconciler/src/ReactFiberSuspenseComponent.old.js +++ b/packages/react-reconciler/src/ReactFiberSuspenseComponent.old.js @@ -13,6 +13,7 @@ import type {SuspenseInstance} from './ReactFiberHostConfig'; import type {Lane} from './ReactFiberLane.old'; import type {TreeContext} from './ReactFiberTreeContext.old'; +import {enableSuspenseAvoidThisFallback} from 'shared/ReactFeatureFlags'; import {SuspenseComponent, SuspenseListComponent} from './ReactWorkTags'; import {NoFlags, DidCapture} from './ReactFiberFlags'; import { @@ -81,7 +82,10 @@ export function shouldCaptureSuspense( } const props = workInProgress.memoizedProps; // Regular boundaries always capture. - if (props.unstable_avoidThisFallback !== true) { + if ( + !enableSuspenseAvoidThisFallback || + props.unstable_avoidThisFallback !== true + ) { return true; } // If it's a boundary we should avoid, then we prefer to bubble up to the diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index bf87304fae18f..e78615de882f8 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -40,7 +40,7 @@ export const disableModulePatternComponents = true; export const warnUnstableRenderSubtreeIntoContainer = false; export const warnAboutSpreadingKeyToJSX = false; export const warnOnSubscriptionInsideStartTransition = false; -export const enableSuspenseAvoidThisFallback = false; +export const enableSuspenseAvoidThisFallback = true; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; export const enableClientRenderFallbackOnHydrationMismatch = true; export const enableComponentStackLocations = true; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index e96c9fc2023ac..019c5565681a7 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -40,7 +40,7 @@ export const disableModulePatternComponents = true; export const warnUnstableRenderSubtreeIntoContainer = false; export const warnAboutSpreadingKeyToJSX = false; export const warnOnSubscriptionInsideStartTransition = false; -export const enableSuspenseAvoidThisFallback = false; +export const enableSuspenseAvoidThisFallback = true; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = true; export const enableClientRenderFallbackOnHydrationMismatch = true; export const enableComponentStackLocations = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index a46b66fb20db0..557c7632a342c 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -50,7 +50,7 @@ export const enableProfilerNestedUpdateScheduledHook = export const enableUpdaterTracking = __PROFILE__; export const enableSuspenseLayoutEffectSemantics = true; -export const enableSuspenseAvoidThisFallback = false; +export const enableSuspenseAvoidThisFallback = true; // Logs additional User Timing API marks for use with an experimental profiling tool. export const enableSchedulingProfiler = From d1ae53730960a1ed1d4eaaf8d30acc87f6d5a706 Mon Sep 17 00:00:00 2001 From: Marco Salazar Date: Wed, 8 Dec 2021 10:56:14 -0500 Subject: [PATCH 2/4] avoidThisFallback flag --- .../__tests__/ReactSuspenseWithNoopRenderer-test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js index 6c0b4076e6187..56b2e7f9190a1 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js @@ -2234,7 +2234,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(ReactNoop).toMatchRenderedOutput('Loading...'); }); - // @gate enableCache + // @gate enableCache && enableSuspenseAvoidThisFallback it('shows the parent fallback if the inner fallback should be avoided', async () => { function Foo({showC}) { Scheduler.unstable_yieldValue('Foo'); @@ -2340,7 +2340,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(ReactNoop.getChildren()).toEqual([span('A'), span('C'), span('B')]); }); - // @gate enableCache + // @gate enableCache && enableSuspenseAvoidThisFallback it('favors showing the inner fallback for nested top level avoided fallback', async () => { function Foo({showB}) { Scheduler.unstable_yieldValue('Foo'); @@ -2372,7 +2372,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(ReactNoop.getChildren()).toEqual([span('A'), span('Loading B...')]); }); - // @gate enableCache + // @gate enableCache && enableSuspenseAvoidThisFallback it('keeps showing an avoided parent fallback if it is already showing', async () => { function Foo({showB}) { Scheduler.unstable_yieldValue('Foo'); @@ -2865,7 +2865,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { }); }); - // @gate enableCache + // @gate enableCache && enableSuspenseAvoidThisFallback it('do not show placeholder when updating an avoided boundary with startTransition', async () => { function App({page}) { return ( @@ -2909,7 +2909,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { ); }); - // @gate enableCache + // @gate enableCache && enableSuspenseAvoidThisFallback it('do not show placeholder when mounting an avoided boundary with startTransition', async () => { function App({page}) { return ( From 86e0e888f24cb3edbd458b52aaafe1291dd2b7e2 Mon Sep 17 00:00:00 2001 From: Marco Salazar Date: Wed, 8 Dec 2021 11:05:06 -0500 Subject: [PATCH 3/4] missed a spot --- .../react-reconciler/src/__tests__/ReactSuspenseList-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js index d357094f78c96..8aff360fe661a 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js @@ -688,7 +688,7 @@ describe('ReactSuspenseList', () => { ); }); - // @gate enableSuspenseList + // @gate enableSuspenseList && enableSuspenseAvoidThisFallback it('avoided boundaries can be coordinate with SuspenseList', async () => { const A = createAsyncText('A'); const B = createAsyncText('B'); From edb88abfc63024232203d30a11bed00e6d516007 Mon Sep 17 00:00:00 2001 From: Marco Salazar Date: Wed, 8 Dec 2021 11:10:05 -0500 Subject: [PATCH 4/4] rm gating --- .../src/__tests__/ReactSuspenseWithNoopRenderer-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js index 56b2e7f9190a1..241af6432c739 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js @@ -2340,7 +2340,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(ReactNoop.getChildren()).toEqual([span('A'), span('C'), span('B')]); }); - // @gate enableCache && enableSuspenseAvoidThisFallback + // @gate enableCache it('favors showing the inner fallback for nested top level avoided fallback', async () => { function Foo({showB}) { Scheduler.unstable_yieldValue('Foo');