diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.new.js b/packages/react-reconciler/src/ReactFiberCommitWork.new.js index 6712e27bd28e1..0c89aba8cdbdd 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.new.js @@ -42,6 +42,7 @@ import { enableUpdaterTracking, enableCache, enableTransitionTracing, + enableFlipOffscreenUnhideOrder, } from 'shared/ReactFeatureFlags'; import { FunctionComponent, @@ -2270,28 +2271,56 @@ function commitMutationEffectsOnFiber( const isHidden = newState !== null; const offscreenBoundary: Fiber = finishedWork; - if (supportsMutation) { - // TODO: This needs to run whenever there's an insertion or update - // inside a hidden Offscreen tree. - hideOrUnhideAllChildren(offscreenBoundary, isHidden); - } - - if (enableSuspenseLayoutEffectSemantics) { - if (isHidden) { - if (!wasHidden) { - if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { - nextEffect = offscreenBoundary; - let offscreenChild = offscreenBoundary.child; - while (offscreenChild !== null) { - nextEffect = offscreenChild; - disappearLayoutEffects_begin(offscreenChild); - offscreenChild = offscreenChild.sibling; + if (enableFlipOffscreenUnhideOrder) { + if (enableSuspenseLayoutEffectSemantics) { + if (isHidden) { + if (!wasHidden) { + if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { + nextEffect = offscreenBoundary; + let offscreenChild = offscreenBoundary.child; + while (offscreenChild !== null) { + nextEffect = offscreenChild; + disappearLayoutEffects_begin(offscreenChild); + offscreenChild = offscreenChild.sibling; + } } } + } else { + if (wasHidden) { + // TODO: Move re-appear call here for symmetry? + } } - } else { - if (wasHidden) { - // TODO: Move re-appear call here for symmetry? + } + + if (supportsMutation) { + // TODO: This needs to run whenever there's an insertion or update + // inside a hidden Offscreen tree. + hideOrUnhideAllChildren(offscreenBoundary, isHidden); + } + } else { + if (supportsMutation) { + // TODO: This needs to run whenever there's an insertion or update + // inside a hidden Offscreen tree. + hideOrUnhideAllChildren(offscreenBoundary, isHidden); + } + + if (enableSuspenseLayoutEffectSemantics) { + if (isHidden) { + if (!wasHidden) { + if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { + nextEffect = offscreenBoundary; + let offscreenChild = offscreenBoundary.child; + while (offscreenChild !== null) { + nextEffect = offscreenChild; + disappearLayoutEffects_begin(offscreenChild); + offscreenChild = offscreenChild.sibling; + } + } + } + } else { + if (wasHidden) { + // TODO: Move re-appear call here for symmetry? + } } } } diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.old.js b/packages/react-reconciler/src/ReactFiberCommitWork.old.js index a00355b6f5fc8..0cd78fdc13a3e 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.old.js @@ -42,6 +42,7 @@ import { enableUpdaterTracking, enableCache, enableTransitionTracing, + enableFlipOffscreenUnhideOrder, } from 'shared/ReactFeatureFlags'; import { FunctionComponent, @@ -2270,28 +2271,56 @@ function commitMutationEffectsOnFiber( const isHidden = newState !== null; const offscreenBoundary: Fiber = finishedWork; - if (supportsMutation) { - // TODO: This needs to run whenever there's an insertion or update - // inside a hidden Offscreen tree. - hideOrUnhideAllChildren(offscreenBoundary, isHidden); - } - - if (enableSuspenseLayoutEffectSemantics) { - if (isHidden) { - if (!wasHidden) { - if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { - nextEffect = offscreenBoundary; - let offscreenChild = offscreenBoundary.child; - while (offscreenChild !== null) { - nextEffect = offscreenChild; - disappearLayoutEffects_begin(offscreenChild); - offscreenChild = offscreenChild.sibling; + if (enableFlipOffscreenUnhideOrder) { + if (enableSuspenseLayoutEffectSemantics) { + if (isHidden) { + if (!wasHidden) { + if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { + nextEffect = offscreenBoundary; + let offscreenChild = offscreenBoundary.child; + while (offscreenChild !== null) { + nextEffect = offscreenChild; + disappearLayoutEffects_begin(offscreenChild); + offscreenChild = offscreenChild.sibling; + } } } + } else { + if (wasHidden) { + // TODO: Move re-appear call here for symmetry? + } } - } else { - if (wasHidden) { - // TODO: Move re-appear call here for symmetry? + } + + if (supportsMutation) { + // TODO: This needs to run whenever there's an insertion or update + // inside a hidden Offscreen tree. + hideOrUnhideAllChildren(offscreenBoundary, isHidden); + } + } else { + if (supportsMutation) { + // TODO: This needs to run whenever there's an insertion or update + // inside a hidden Offscreen tree. + hideOrUnhideAllChildren(offscreenBoundary, isHidden); + } + + if (enableSuspenseLayoutEffectSemantics) { + if (isHidden) { + if (!wasHidden) { + if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { + nextEffect = offscreenBoundary; + let offscreenChild = offscreenBoundary.child; + while (offscreenChild !== null) { + nextEffect = offscreenChild; + disappearLayoutEffects_begin(offscreenChild); + offscreenChild = offscreenChild.sibling; + } + } + } + } else { + if (wasHidden) { + // TODO: Move re-appear call here for symmetry? + } } } } diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 218a3514f0f34..d755508595728 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -39,6 +39,7 @@ export const skipUnmountedBoundaries = true; // // TODO: Finish rolling out in www export const enableSuspenseLayoutEffectSemantics = true; +export const enableFlipOffscreenUnhideOrder = false; // TODO: Finish rolling out in www export const enableClientRenderFallbackOnTextMismatch = true; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 6baef59489978..b5e38b01398c1 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -58,6 +58,7 @@ export const disableNativeComponentFrames = false; export const skipUnmountedBoundaries = false; export const deletedTreeCleanUpLevel = 3; export const enableSuspenseLayoutEffectSemantics = false; +export const enableFlipOffscreenUnhideOrder = false; export const enableGetInspectorDataForInstanceInProduction = true; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index e9398deee80db..b443027f47ac5 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false; export const skipUnmountedBoundaries = false; export const deletedTreeCleanUpLevel = 3; export const enableSuspenseLayoutEffectSemantics = false; +export const enableFlipOffscreenUnhideOrder = false; export const enableGetInspectorDataForInstanceInProduction = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index c3ca7f565c737..1524e03f388d7 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false; export const skipUnmountedBoundaries = false; export const deletedTreeCleanUpLevel = 3; export const enableSuspenseLayoutEffectSemantics = false; +export const enableFlipOffscreenUnhideOrder = false; export const enableGetInspectorDataForInstanceInProduction = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index d186c1852e6b3..76e9f76e24df8 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -44,6 +44,7 @@ export const disableNativeComponentFrames = false; export const skipUnmountedBoundaries = false; export const deletedTreeCleanUpLevel = 3; export const enableSuspenseLayoutEffectSemantics = false; +export const enableFlipOffscreenUnhideOrder = false; export const enableGetInspectorDataForInstanceInProduction = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index e258b155c2c11..f9b2d7046869c 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false; export const skipUnmountedBoundaries = false; export const deletedTreeCleanUpLevel = 3; export const enableSuspenseLayoutEffectSemantics = false; +export const enableFlipOffscreenUnhideOrder = false; export const enableGetInspectorDataForInstanceInProduction = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index d173aaa1b30a9..097482c4ae990 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false; export const skipUnmountedBoundaries = false; export const deletedTreeCleanUpLevel = 3; export const enableSuspenseLayoutEffectSemantics = false; +export const enableFlipOffscreenUnhideOrder = false; export const enableGetInspectorDataForInstanceInProduction = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index c2842d955938d..ad3e316fb862e 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false; export const skipUnmountedBoundaries = true; export const deletedTreeCleanUpLevel = 3; export const enableSuspenseLayoutEffectSemantics = false; +export const enableFlipOffscreenUnhideOrder = false; export const enableGetInspectorDataForInstanceInProduction = false; export const enableNewReconciler = false; export const deferRenderPhaseUpdateToNextBatch = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 253cb58a2d1f6..2cf38eeabb63b 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -29,6 +29,7 @@ export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __ export const enableClientRenderFallbackOnTextMismatch = __VARIANT__; export const enableTransitionTracing = __VARIANT__; export const enableSymbolFallbackForWWW = __VARIANT__; +export const enableFlipOffscreenUnhideOrder = __VARIANT__; // Enable this flag to help with concurrent mode debugging. // It logs information to the console about React scheduling, rendering, and commit phases. // diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 5a8f89bae8406..d54a7c142de03 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -33,6 +33,7 @@ export const { enableSyncDefaultUpdates, enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, enableClientRenderFallbackOnTextMismatch, + enableFlipOffscreenUnhideOrder, } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build.