Skip to content

Commit 99eef9e

Browse files
authored
Hide children of Offscreen after destroy effects (#24446)
1 parent 6c36aee commit 99eef9e

12 files changed

+106
-38
lines changed

Diff for: packages/react-reconciler/src/ReactFiberCommitWork.new.js

+48-19
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
enableUpdaterTracking,
4343
enableCache,
4444
enableTransitionTracing,
45+
enableFlipOffscreenUnhideOrder,
4546
} from 'shared/ReactFeatureFlags';
4647
import {
4748
FunctionComponent,
@@ -2270,28 +2271,56 @@ function commitMutationEffectsOnFiber(
22702271
const isHidden = newState !== null;
22712272
const offscreenBoundary: Fiber = finishedWork;
22722273

2273-
if (supportsMutation) {
2274-
// TODO: This needs to run whenever there's an insertion or update
2275-
// inside a hidden Offscreen tree.
2276-
hideOrUnhideAllChildren(offscreenBoundary, isHidden);
2277-
}
2278-
2279-
if (enableSuspenseLayoutEffectSemantics) {
2280-
if (isHidden) {
2281-
if (!wasHidden) {
2282-
if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
2283-
nextEffect = offscreenBoundary;
2284-
let offscreenChild = offscreenBoundary.child;
2285-
while (offscreenChild !== null) {
2286-
nextEffect = offscreenChild;
2287-
disappearLayoutEffects_begin(offscreenChild);
2288-
offscreenChild = offscreenChild.sibling;
2274+
if (enableFlipOffscreenUnhideOrder) {
2275+
if (enableSuspenseLayoutEffectSemantics) {
2276+
if (isHidden) {
2277+
if (!wasHidden) {
2278+
if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
2279+
nextEffect = offscreenBoundary;
2280+
let offscreenChild = offscreenBoundary.child;
2281+
while (offscreenChild !== null) {
2282+
nextEffect = offscreenChild;
2283+
disappearLayoutEffects_begin(offscreenChild);
2284+
offscreenChild = offscreenChild.sibling;
2285+
}
22892286
}
22902287
}
2288+
} else {
2289+
if (wasHidden) {
2290+
// TODO: Move re-appear call here for symmetry?
2291+
}
22912292
}
2292-
} else {
2293-
if (wasHidden) {
2294-
// TODO: Move re-appear call here for symmetry?
2293+
}
2294+
2295+
if (supportsMutation) {
2296+
// TODO: This needs to run whenever there's an insertion or update
2297+
// inside a hidden Offscreen tree.
2298+
hideOrUnhideAllChildren(offscreenBoundary, isHidden);
2299+
}
2300+
} else {
2301+
if (supportsMutation) {
2302+
// TODO: This needs to run whenever there's an insertion or update
2303+
// inside a hidden Offscreen tree.
2304+
hideOrUnhideAllChildren(offscreenBoundary, isHidden);
2305+
}
2306+
2307+
if (enableSuspenseLayoutEffectSemantics) {
2308+
if (isHidden) {
2309+
if (!wasHidden) {
2310+
if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
2311+
nextEffect = offscreenBoundary;
2312+
let offscreenChild = offscreenBoundary.child;
2313+
while (offscreenChild !== null) {
2314+
nextEffect = offscreenChild;
2315+
disappearLayoutEffects_begin(offscreenChild);
2316+
offscreenChild = offscreenChild.sibling;
2317+
}
2318+
}
2319+
}
2320+
} else {
2321+
if (wasHidden) {
2322+
// TODO: Move re-appear call here for symmetry?
2323+
}
22952324
}
22962325
}
22972326
}

Diff for: packages/react-reconciler/src/ReactFiberCommitWork.old.js

+48-19
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
enableUpdaterTracking,
4343
enableCache,
4444
enableTransitionTracing,
45+
enableFlipOffscreenUnhideOrder,
4546
} from 'shared/ReactFeatureFlags';
4647
import {
4748
FunctionComponent,
@@ -2270,28 +2271,56 @@ function commitMutationEffectsOnFiber(
22702271
const isHidden = newState !== null;
22712272
const offscreenBoundary: Fiber = finishedWork;
22722273

2273-
if (supportsMutation) {
2274-
// TODO: This needs to run whenever there's an insertion or update
2275-
// inside a hidden Offscreen tree.
2276-
hideOrUnhideAllChildren(offscreenBoundary, isHidden);
2277-
}
2278-
2279-
if (enableSuspenseLayoutEffectSemantics) {
2280-
if (isHidden) {
2281-
if (!wasHidden) {
2282-
if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
2283-
nextEffect = offscreenBoundary;
2284-
let offscreenChild = offscreenBoundary.child;
2285-
while (offscreenChild !== null) {
2286-
nextEffect = offscreenChild;
2287-
disappearLayoutEffects_begin(offscreenChild);
2288-
offscreenChild = offscreenChild.sibling;
2274+
if (enableFlipOffscreenUnhideOrder) {
2275+
if (enableSuspenseLayoutEffectSemantics) {
2276+
if (isHidden) {
2277+
if (!wasHidden) {
2278+
if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
2279+
nextEffect = offscreenBoundary;
2280+
let offscreenChild = offscreenBoundary.child;
2281+
while (offscreenChild !== null) {
2282+
nextEffect = offscreenChild;
2283+
disappearLayoutEffects_begin(offscreenChild);
2284+
offscreenChild = offscreenChild.sibling;
2285+
}
22892286
}
22902287
}
2288+
} else {
2289+
if (wasHidden) {
2290+
// TODO: Move re-appear call here for symmetry?
2291+
}
22912292
}
2292-
} else {
2293-
if (wasHidden) {
2294-
// TODO: Move re-appear call here for symmetry?
2293+
}
2294+
2295+
if (supportsMutation) {
2296+
// TODO: This needs to run whenever there's an insertion or update
2297+
// inside a hidden Offscreen tree.
2298+
hideOrUnhideAllChildren(offscreenBoundary, isHidden);
2299+
}
2300+
} else {
2301+
if (supportsMutation) {
2302+
// TODO: This needs to run whenever there's an insertion or update
2303+
// inside a hidden Offscreen tree.
2304+
hideOrUnhideAllChildren(offscreenBoundary, isHidden);
2305+
}
2306+
2307+
if (enableSuspenseLayoutEffectSemantics) {
2308+
if (isHidden) {
2309+
if (!wasHidden) {
2310+
if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
2311+
nextEffect = offscreenBoundary;
2312+
let offscreenChild = offscreenBoundary.child;
2313+
while (offscreenChild !== null) {
2314+
nextEffect = offscreenChild;
2315+
disappearLayoutEffects_begin(offscreenChild);
2316+
offscreenChild = offscreenChild.sibling;
2317+
}
2318+
}
2319+
}
2320+
} else {
2321+
if (wasHidden) {
2322+
// TODO: Move re-appear call here for symmetry?
2323+
}
22952324
}
22962325
}
22972326
}

Diff for: packages/shared/ReactFeatureFlags.js

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const skipUnmountedBoundaries = true;
3838
//
3939
// TODO: Finish rolling out in www
4040
export const enableSuspenseLayoutEffectSemantics = true;
41+
export const enableFlipOffscreenUnhideOrder = false;
4142

4243
// TODO: Finish rolling out in www
4344
export const enableClientRenderFallbackOnTextMismatch = true;

Diff for: packages/shared/forks/ReactFeatureFlags.native-fb.js

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export const disableNativeComponentFrames = false;
5959
export const skipUnmountedBoundaries = false;
6060
export const deletedTreeCleanUpLevel = 3;
6161
export const enableSuspenseLayoutEffectSemantics = false;
62+
export const enableFlipOffscreenUnhideOrder = false;
6263
export const enableGetInspectorDataForInstanceInProduction = true;
6364
export const enableNewReconciler = false;
6465
export const deferRenderPhaseUpdateToNextBatch = false;

Diff for: packages/shared/forks/ReactFeatureFlags.native-oss.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
4949
export const skipUnmountedBoundaries = false;
5050
export const deletedTreeCleanUpLevel = 3;
5151
export const enableSuspenseLayoutEffectSemantics = false;
52+
export const enableFlipOffscreenUnhideOrder = false;
5253
export const enableGetInspectorDataForInstanceInProduction = false;
5354
export const enableNewReconciler = false;
5455
export const deferRenderPhaseUpdateToNextBatch = false;

Diff for: packages/shared/forks/ReactFeatureFlags.test-renderer.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
4949
export const skipUnmountedBoundaries = false;
5050
export const deletedTreeCleanUpLevel = 3;
5151
export const enableSuspenseLayoutEffectSemantics = false;
52+
export const enableFlipOffscreenUnhideOrder = false;
5253
export const enableGetInspectorDataForInstanceInProduction = false;
5354
export const enableNewReconciler = false;
5455
export const deferRenderPhaseUpdateToNextBatch = false;

Diff for: packages/shared/forks/ReactFeatureFlags.test-renderer.native.js

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const disableNativeComponentFrames = false;
4444
export const skipUnmountedBoundaries = false;
4545
export const deletedTreeCleanUpLevel = 3;
4646
export const enableSuspenseLayoutEffectSemantics = false;
47+
export const enableFlipOffscreenUnhideOrder = false;
4748
export const enableGetInspectorDataForInstanceInProduction = false;
4849
export const enableNewReconciler = false;
4950
export const deferRenderPhaseUpdateToNextBatch = false;

Diff for: packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
4949
export const skipUnmountedBoundaries = false;
5050
export const deletedTreeCleanUpLevel = 3;
5151
export const enableSuspenseLayoutEffectSemantics = false;
52+
export const enableFlipOffscreenUnhideOrder = false;
5253
export const enableGetInspectorDataForInstanceInProduction = false;
5354
export const enableNewReconciler = false;
5455
export const deferRenderPhaseUpdateToNextBatch = false;

Diff for: packages/shared/forks/ReactFeatureFlags.testing.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
4949
export const skipUnmountedBoundaries = false;
5050
export const deletedTreeCleanUpLevel = 3;
5151
export const enableSuspenseLayoutEffectSemantics = false;
52+
export const enableFlipOffscreenUnhideOrder = false;
5253
export const enableGetInspectorDataForInstanceInProduction = false;
5354
export const enableNewReconciler = false;
5455
export const deferRenderPhaseUpdateToNextBatch = false;

Diff for: packages/shared/forks/ReactFeatureFlags.testing.www.js

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
4949
export const skipUnmountedBoundaries = true;
5050
export const deletedTreeCleanUpLevel = 3;
5151
export const enableSuspenseLayoutEffectSemantics = false;
52+
export const enableFlipOffscreenUnhideOrder = false;
5253
export const enableGetInspectorDataForInstanceInProduction = false;
5354
export const enableNewReconciler = false;
5455
export const deferRenderPhaseUpdateToNextBatch = false;

Diff for: packages/shared/forks/ReactFeatureFlags.www-dynamic.js

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __
2929
export const enableClientRenderFallbackOnTextMismatch = __VARIANT__;
3030
export const enableTransitionTracing = __VARIANT__;
3131
export const enableSymbolFallbackForWWW = __VARIANT__;
32+
export const enableFlipOffscreenUnhideOrder = __VARIANT__;
3233
// Enable this flag to help with concurrent mode debugging.
3334
// It logs information to the console about React scheduling, rendering, and commit phases.
3435
//

Diff for: packages/shared/forks/ReactFeatureFlags.www.js

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const {
3333
enableSyncDefaultUpdates,
3434
enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
3535
enableClientRenderFallbackOnTextMismatch,
36+
enableFlipOffscreenUnhideOrder,
3637
} = dynamicFeatureFlags;
3738

3839
// On WWW, __EXPERIMENTAL__ is used for a new modern build.

0 commit comments

Comments
 (0)