Hide children of Offscreen after destroy effects (#24446)
Ricky committed
May 3, 2022 at 10:16 UTC
99eef9e2df7b6aade461a1a958eb3838239e72c4
12 files changed
+106
-38
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+48
-19
@@ -42,6 +42,7 @@ import {
42
enableUpdaterTracking,
43
enableCache,
44
enableTransitionTracing,
45
+ enableFlipOffscreenUnhideOrder,
46
} from 'shared/ReactFeatureFlags';
47
import {
48
FunctionComponent,
@@ -2270,28 +2271,56 @@ function commitMutationEffectsOnFiber(
2271
const isHidden = newState !== null;
2272
const offscreenBoundary: Fiber = finishedWork;
2273
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
+ }
2286
}
2287
}
2288
+ } else {
2289
+ if (wasHidden) {
2290
+ // TODO: Move re-appear call here for symmetry?
2291
+ }
2292
}
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
+ }
2324
}
2325
}
2326
}
packages/react-reconciler/src/ReactFiberCommitWork.old.js
+48
-19
@@ -42,6 +42,7 @@ import {
42
enableUpdaterTracking,
43
enableCache,
44
enableTransitionTracing,
45
+ enableFlipOffscreenUnhideOrder,
46
} from 'shared/ReactFeatureFlags';
47
import {
48
FunctionComponent,
@@ -2270,28 +2271,56 @@ function commitMutationEffectsOnFiber(
2271
const isHidden = newState !== null;
2272
const offscreenBoundary: Fiber = finishedWork;
2273
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
+ }
2286
}
2287
}
2288
+ } else {
2289
+ if (wasHidden) {
2290
+ // TODO: Move re-appear call here for symmetry?
2291
+ }
2292
}
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
+ }
2324
}
2325
}
2326
}
packages/shared/ReactFeatureFlags.js
+1
@@ -38,6 +38,7 @@ export const skipUnmountedBoundaries = true;
38
//
39
// TODO: Finish rolling out in www
40
export const enableSuspenseLayoutEffectSemantics = true;
41
+export const enableFlipOffscreenUnhideOrder = false;
42
43
// TODO: Finish rolling out in www
44
export const enableClientRenderFallbackOnTextMismatch = true;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -59,6 +59,7 @@ export const disableNativeComponentFrames = false;
59
export const skipUnmountedBoundaries = false;
60
export const deletedTreeCleanUpLevel = 3;
61
export const enableSuspenseLayoutEffectSemantics = false;
62
+export const enableFlipOffscreenUnhideOrder = false;
63
export const enableGetInspectorDataForInstanceInProduction = true;
64
export const enableNewReconciler = false;
65
export const deferRenderPhaseUpdateToNextBatch = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
49
export const skipUnmountedBoundaries = false;
50
export const deletedTreeCleanUpLevel = 3;
51
export const enableSuspenseLayoutEffectSemantics = false;
52
+export const enableFlipOffscreenUnhideOrder = false;
53
export const enableGetInspectorDataForInstanceInProduction = false;
54
export const enableNewReconciler = false;
55
export const deferRenderPhaseUpdateToNextBatch = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
49
export const skipUnmountedBoundaries = false;
50
export const deletedTreeCleanUpLevel = 3;
51
export const enableSuspenseLayoutEffectSemantics = false;
52
+export const enableFlipOffscreenUnhideOrder = false;
53
export const enableGetInspectorDataForInstanceInProduction = false;
54
export const enableNewReconciler = false;
55
export const deferRenderPhaseUpdateToNextBatch = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+1
@@ -44,6 +44,7 @@ export const disableNativeComponentFrames = false;
44
export const skipUnmountedBoundaries = false;
45
export const deletedTreeCleanUpLevel = 3;
46
export const enableSuspenseLayoutEffectSemantics = false;
47
+export const enableFlipOffscreenUnhideOrder = false;
48
export const enableGetInspectorDataForInstanceInProduction = false;
49
export const enableNewReconciler = false;
50
export const deferRenderPhaseUpdateToNextBatch = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
49
export const skipUnmountedBoundaries = false;
50
export const deletedTreeCleanUpLevel = 3;
51
export const enableSuspenseLayoutEffectSemantics = false;
52
+export const enableFlipOffscreenUnhideOrder = false;
53
export const enableGetInspectorDataForInstanceInProduction = false;
54
export const enableNewReconciler = false;
55
export const deferRenderPhaseUpdateToNextBatch = false;
packages/shared/forks/ReactFeatureFlags.testing.js
+1
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
49
export const skipUnmountedBoundaries = false;
50
export const deletedTreeCleanUpLevel = 3;
51
export const enableSuspenseLayoutEffectSemantics = false;
52
+export const enableFlipOffscreenUnhideOrder = false;
53
export const enableGetInspectorDataForInstanceInProduction = false;
54
export const enableNewReconciler = false;
55
export const deferRenderPhaseUpdateToNextBatch = false;
packages/shared/forks/ReactFeatureFlags.testing.www.js
+1
@@ -49,6 +49,7 @@ export const disableNativeComponentFrames = false;
49
export const skipUnmountedBoundaries = true;
50
export const deletedTreeCleanUpLevel = 3;
51
export const enableSuspenseLayoutEffectSemantics = false;
52
+export const enableFlipOffscreenUnhideOrder = false;
53
export const enableGetInspectorDataForInstanceInProduction = false;
54
export const enableNewReconciler = false;
55
export const deferRenderPhaseUpdateToNextBatch = false;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+1
@@ -29,6 +29,7 @@ export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __
29
export const enableClientRenderFallbackOnTextMismatch = __VARIANT__;
30
export const enableTransitionTracing = __VARIANT__;
31
export const enableSymbolFallbackForWWW = __VARIANT__;
32
+export const enableFlipOffscreenUnhideOrder = __VARIANT__;
33
// Enable this flag to help with concurrent mode debugging.
34
// It logs information to the console about React scheduling, rendering, and commit phases.
35
//
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -33,6 +33,7 @@ export const {
33
enableSyncDefaultUpdates,
34
enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
35
enableClientRenderFallbackOnTextMismatch,
36
+ enableFlipOffscreenUnhideOrder,
37
} = dynamicFeatureFlags;
38
39
// On WWW, __EXPERIMENTAL__ is used for a new modern build.