diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index 02b2ec1a45f68..3e344d33261e8 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 8733ab0a4e51f..5192d6b2fc99d 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/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'); diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js index 6c0b4076e6187..241af6432c739 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'); @@ -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 ( diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 51bbc5a1627df..ef3f01e583c24 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 f62dc8af4960d..ea7a8f9995fc8 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 cffa189840f8c..a1e5a48aabb77 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 =