@samitouri / QOS-React-1 / commits / d3d4d3a46b

Call cleanup of insertion effects when hidden (#30954)

Insertion effects do not unmount when a subtree is removed while offscreen. Current behavior for an insertion effect is if the component goes - *visible -> removed:* calls insertion effect cleanup - *visible -> offscreen -> removed:* insertion effect cleanup is never called This makes it so we always call insertion effect cleanup when removing the component. Likely also fixes https://github.com/facebook/react/issues/26670 --------- Co-authored-by: Rick Hanlon <rickhanlonii@fb.com>

Jan Kassens committed Sep 13, 2024 at 13:18 UTC d3d4d3a46b014ab0f6edc443c19fcdba09105f20
13 files changed +366 -5
packages/react-reconciler/src/ReactFiberCommitWork.js
+74 -1
@@ -40,6 +40,7 @@ import type {
40 import {
41 alwaysThrottleRetries,
42 enableCreateEventHandleAPI,
43 + enableHiddenSubtreeInsertionEffectCleanup,
44 enablePersistedModeClonedFlag,
45 enableProfilerTimer,
46 enableProfilerCommitHooks,
@@ -147,6 +148,7 @@ import {
148 getExecutionContext,
149 CommitContext,
150 NoContext,
151 + setIsRunningInsertionEffect,
152 } from './ReactFiberWorkLoop';
153 import {
154 NoFlags as NoHookEffect,
@@ -1324,7 +1326,78 @@ function commitDeletionEffectsOnFiber(
1326 case ForwardRef:
1327 case MemoComponent:
1328 case SimpleMemoComponent: {
1327 - if (!offscreenSubtreeWasHidden) {
1329 + if (enableHiddenSubtreeInsertionEffectCleanup) {
1330 + // When deleting a fiber, we may need to destroy insertion or layout effects.
1331 + // Insertion effects are not destroyed on hidden, only when destroyed, so now
1332 + // we need to destroy them. Layout effects are destroyed when hidden, so
1333 + // we only need to destroy them if the tree is visible.
1334 + const updateQueue: FunctionComponentUpdateQueue | null =
1335 + (deletedFiber.updateQueue: any);
1336 + if (updateQueue !== null) {
1337 + const lastEffect = updateQueue.lastEffect;
1338 + if (lastEffect !== null) {
1339 + const firstEffect = lastEffect.next;
1340 +
1341 + let effect = firstEffect;
1342 + do {
1343 + const tag = effect.tag;
1344 + const inst = effect.inst;
1345 + const destroy = inst.destroy;
1346 + if (destroy !== undefined) {
1347 + if ((tag & HookInsertion) !== NoHookEffect) {
1348 + // TODO: add insertion effect marks and profiling.
1349 + if (__DEV__) {
1350 + setIsRunningInsertionEffect(true);
1351 + }
1352 +
1353 + inst.destroy = undefined;
1354 + safelyCallDestroy(
1355 + deletedFiber,
1356 + nearestMountedAncestor,
1357 + destroy,
1358 + );
1359 +
1360 + if (__DEV__) {
1361 + setIsRunningInsertionEffect(false);
1362 + }
1363 + } else if (
1364 + !offscreenSubtreeWasHidden &&
1365 + (tag & HookLayout) !== NoHookEffect
1366 + ) {
1367 + // Offscreen fibers already unmounted their layout effects.
1368 + // We only need to destroy layout effects for visible trees.
1369 + if (enableSchedulingProfiler) {
1370 + markComponentLayoutEffectUnmountStarted(deletedFiber);
1371 + }
1372 +
1373 + if (shouldProfile(deletedFiber)) {
1374 + startLayoutEffectTimer();
1375 + inst.destroy = undefined;
1376 + safelyCallDestroy(
1377 + deletedFiber,
1378 + nearestMountedAncestor,
1379 + destroy,
1380 + );
1381 + recordLayoutEffectDuration(deletedFiber);
1382 + } else {
1383 + inst.destroy = undefined;
1384 + safelyCallDestroy(
1385 + deletedFiber,
1386 + nearestMountedAncestor,
1387 + destroy,
1388 + );
1389 + }
1390 +
1391 + if (enableSchedulingProfiler) {
1392 + markComponentLayoutEffectUnmountStopped();
1393 + }
1394 + }
1395 + }
1396 + effect = effect.next;
1397 + } while (effect !== firstEffect);
1398 + }
1399 + }
1400 + } else if (!offscreenSubtreeWasHidden) {
1401 const updateQueue: FunctionComponentUpdateQueue | null =
1402 (deletedFiber.updateQueue: any);
1403 if (updateQueue !== null) {
packages/react-reconciler/src/__tests__/Activity-test.js
+85
@@ -7,6 +7,7 @@ let Activity;
7 let useState;
8 let useLayoutEffect;
9 let useEffect;
10 +let useInsertionEffect;
11 let useMemo;
12 let useRef;
13 let startTransition;
@@ -25,6 +26,7 @@ describe('Activity', () => {
26 LegacyHidden = React.unstable_LegacyHidden;
27 Activity = React.unstable_Activity;
28 useState = React.useState;
29 + useInsertionEffect = React.useInsertionEffect;
30 useLayoutEffect = React.useLayoutEffect;
31 useEffect = React.useEffect;
32 useMemo = React.useMemo;
@@ -43,6 +45,13 @@ describe('Activity', () => {
45 }
46
47 function LoggedText({text, children}) {
48 + useInsertionEffect(() => {
49 + Scheduler.log(`mount insertion ${text}`);
50 + return () => {
51 + Scheduler.log(`unmount insertion ${text}`);
52 + };
53 + });
54 +
55 useEffect(() => {
56 Scheduler.log(`mount ${text}`);
57 return () => {
@@ -1436,6 +1445,63 @@ describe('Activity', () => {
1445 );
1446 });
1447
1448 + // @gate enableActivity
1449 + it('insertion effects are not disconnected when the visibility changes', async () => {
1450 + function Child({step}) {
1451 + useInsertionEffect(() => {
1452 + Scheduler.log(`Commit mount [${step}]`);
1453 + return () => {
1454 + Scheduler.log(`Commit unmount [${step}]`);
1455 + };
1456 + }, [step]);
1457 + return <Text text={step} />;
1458 + }
1459 +
1460 + function App({show, step}) {
1461 + return (
1462 + <Activity mode={show ? 'visible' : 'hidden'}>
1463 + {useMemo(
1464 + () => (
1465 + <Child step={step} />
1466 + ),
1467 + [step],
1468 + )}
1469 + </Activity>
1470 + );
1471 + }
1472 +
1473 + const root = ReactNoop.createRoot();
1474 + await act(() => {
1475 + root.render(<App show={true} step={1} />);
1476 + });
1477 + assertLog([1, 'Commit mount [1]']);
1478 + expect(root).toMatchRenderedOutput(<span prop={1} />);
1479 +
1480 + // Hide the tree. This will not unmount insertion effects.
1481 + await act(() => {
1482 + root.render(<App show={false} step={1} />);
1483 + });
1484 + assertLog([]);
1485 + expect(root).toMatchRenderedOutput(<span hidden={true} prop={1} />);
1486 +
1487 + // Update.
1488 + await act(() => {
1489 + root.render(<App show={false} step={2} />);
1490 + });
1491 + // The update is pre-rendered so insertion effects are fired
1492 + assertLog([2, 'Commit unmount [1]', 'Commit mount [2]']);
1493 + expect(root).toMatchRenderedOutput(<span hidden={true} prop={2} />);
1494 +
1495 + // Reveal the tree.
1496 + await act(() => {
1497 + root.render(<App show={true} step={2} />);
1498 + });
1499 + // The update doesn't render because it was already pre-rendered, and the
1500 + // insertion effect already fired.
1501 + assertLog([]);
1502 + expect(root).toMatchRenderedOutput(<span prop={2} />);
1503 + });
1504 +
1505 describe('manual interactivity', () => {
1506 // @gate enableActivity
1507 it('should attach ref only for mode null', async () => {
@@ -1904,6 +1970,9 @@ describe('Activity', () => {
1970 'outer',
1971 'middle',
1972 'inner',
1973 + 'mount insertion inner',
1974 + 'mount insertion middle',
1975 + 'mount insertion outer',
1976 'mount layout inner',
1977 'mount layout middle',
1978 'mount layout outer',
@@ -1964,6 +2033,22 @@ describe('Activity', () => {
2033 });
2034
2035 assertLog(['unmount layout inner', 'unmount inner']);
2036 +
2037 + await act(() => {
2038 + root.render(null);
2039 + });
2040 +
2041 + assertLog([
2042 + 'unmount insertion outer',
2043 + 'unmount layout outer',
2044 + 'unmount insertion middle',
2045 + 'unmount layout middle',
2046 + ...(gate('enableHiddenSubtreeInsertionEffectCleanup')
2047 + ? ['unmount insertion inner']
2048 + : []),
2049 + 'unmount outer',
2050 + 'unmount middle',
2051 + ]);
2052 });
2053
2054 // @gate enableActivity
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+53
@@ -19,6 +19,7 @@ let resolveText;
19 let ReactNoop;
20 let Scheduler;
21 let Suspense;
22 +let Activity;
23 let useState;
24 let useReducer;
25 let useEffect;
@@ -64,6 +65,7 @@ describe('ReactHooksWithNoopRenderer', () => {
65 useTransition = React.useTransition;
66 useDeferredValue = React.useDeferredValue;
67 Suspense = React.Suspense;
68 + Activity = React.unstable_Activity;
69 ContinuousEventPriority =
70 require('react-reconciler/constants').ContinuousEventPriority;
71 if (gate(flags => flags.enableSuspenseList)) {
@@ -2997,6 +2999,57 @@ describe('ReactHooksWithNoopRenderer', () => {
2999 root.render(<NotInsertion />);
3000 });
3001 });
3002 +
3003 + // @gate enableActivity
3004 + it('warns when setState is called from offscreen deleted insertion effect cleanup', async () => {
3005 + function App(props) {
3006 + const [, setX] = useState(0);
3007 + useInsertionEffect(() => {
3008 + if (props.throw) {
3009 + throw Error('No');
3010 + }
3011 + return () => {
3012 + setX(1);
3013 + };
3014 + }, [props.throw, props.foo]);
3015 + return null;
3016 + }
3017 +
3018 + const root = ReactNoop.createRoot();
3019 + await act(() => {
3020 + root.render(
3021 + <Activity mode="hidden">
3022 + <App foo="hello" />
3023 + </Activity>,
3024 + );
3025 + });
3026 +
3027 + if (gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)) {
3028 + await expect(async () => {
3029 + await act(() => {
3030 + root.render(<Activity mode="hidden" />);
3031 + });
3032 + }).toErrorDev(['useInsertionEffect must not schedule updates.']);
3033 + } else {
3034 + await expect(async () => {
3035 + await act(() => {
3036 + root.render(<Activity mode="hidden" />);
3037 + });
3038 + }).toErrorDev([]);
3039 + }
3040 +
3041 + // Should not warn for regular effects after throw.
3042 + function NotInsertion() {
3043 + const [, setX] = useState(0);
3044 + useEffect(() => {
3045 + setX(1);
3046 + }, []);
3047 + return null;
3048 + }
3049 + await act(() => {
3050 + root.render(<NotInsertion />);
3051 + });
3052 + });
3053 });
3054
3055 describe('useLayoutEffect', () => {
packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js
+141 -4
@@ -148,6 +148,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
148
149 function Text({children = null, text}) {
150 Scheduler.log(`Text:${text} render`);
151 + React.useInsertionEffect(() => {
152 + Scheduler.log(`Text:${text} create insertion`);
153 + return () => {
154 + Scheduler.log(`Text:${text} destroy insertion`);
155 + };
156 + }, []);
157 +
158 React.useLayoutEffect(() => {
159 Scheduler.log(`Text:${text} create layout`);
160 return () => {
@@ -268,6 +275,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
275 'Suspend:Async',
276 'Text:Fallback render',
277 'Text:Outside render',
278 + 'Text:Fallback create insertion',
279 + 'Text:Outside create insertion',
280 'Text:Fallback create layout',
281 'Text:Outside create layout',
282 'App create layout',
@@ -298,7 +307,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
307 'Text:Inside:Before render',
308 'AsyncText:Async render',
309 'ClassText:Inside:After render',
310 + 'Text:Fallback destroy insertion',
311 'Text:Fallback destroy layout',
312 + 'Text:Inside:Before create insertion',
313 'Text:Inside:Before create layout',
314 'AsyncText:Async create layout',
315 'ClassText:Inside:After componentDidMount',
@@ -320,9 +331,11 @@ describe('ReactSuspenseEffectsSemantics', () => {
331 });
332 assertLog([
333 'App destroy layout',
334 + 'Text:Inside:Before destroy insertion',
335 'Text:Inside:Before destroy layout',
336 'AsyncText:Async destroy layout',
337 'ClassText:Inside:After componentWillUnmount',
338 + 'Text:Outside destroy insertion',
339 'Text:Outside destroy layout',
340 'App destroy passive',
341 'Text:Inside:Before destroy passive',
@@ -395,6 +408,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
408 'ClassText:Inside:After render',
409 'Text:Fallback render',
410 'Text:Outside render',
411 + 'Text:Inside:Before create insertion',
412 + 'Text:Fallback create insertion',
413 + 'Text:Outside create insertion',
414 'Text:Inside:Before create layout',
415 'ClassText:Inside:After componentDidMount',
416 'Text:Fallback create layout',
@@ -420,6 +436,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
436 });
437 assertLog([
438 'AsyncText:Async render',
439 + 'Text:Fallback destroy insertion',
440 'Text:Fallback destroy layout',
441 'AsyncText:Async create layout',
442 'Text:Fallback destroy passive',
@@ -439,9 +456,11 @@ describe('ReactSuspenseEffectsSemantics', () => {
456 });
457 assertLog([
458 'App destroy layout',
459 + 'Text:Inside:Before destroy insertion',
460 'Text:Inside:Before destroy layout',
461 'AsyncText:Async destroy layout',
462 'ClassText:Inside:After componentWillUnmount',
463 + 'Text:Outside destroy insertion',
464 'Text:Outside destroy layout',
465 'App destroy passive',
466 'Text:Inside:Before destroy passive',
@@ -452,7 +471,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
471 });
472 });
473
455 - describe('layout effects within a tree that re-suspends in an update', () => {
474 + describe('effects within a tree that re-suspends in an update', () => {
475 // @gate enableLegacyCache && !disableLegacyMode
476 it('should not be destroyed or recreated in legacy roots', async () => {
477 function App({children = null}) {
@@ -490,6 +509,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
509 'Text:Inside:Before render',
510 'Text:Inside:After render',
511 'Text:Outside render',
512 + 'Text:Inside:Before create insertion',
513 + 'Text:Inside:After create insertion',
514 + 'Text:Outside create insertion',
515 'Text:Inside:Before create layout',
516 'Text:Inside:After create layout',
517 'Text:Outside create layout',
@@ -522,6 +544,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
544 'Text:Inside:After render',
545 'Text:Fallback render',
546 'Text:Outside render',
547 + 'Text:Fallback create insertion',
548 'Text:Fallback create layout',
549 'Text:Fallback create passive',
550 ]);
@@ -553,6 +576,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
576 });
577 assertLog([
578 'AsyncText:Async render',
579 + 'Text:Fallback destroy insertion',
580 'Text:Fallback destroy layout',
581 'AsyncText:Async create layout',
582 'Text:Fallback destroy passive',
@@ -572,9 +596,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
596 });
597 assertLog([
598 'App destroy layout',
599 + 'Text:Inside:Before destroy insertion',
600 'Text:Inside:Before destroy layout',
601 'AsyncText:Async destroy layout',
602 + 'Text:Inside:After destroy insertion',
603 'Text:Inside:After destroy layout',
604 + 'Text:Outside destroy insertion',
605 'Text:Outside destroy layout',
606 'App destroy passive',
607 'Text:Inside:Before destroy passive',
@@ -620,6 +647,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
647 'Text:Inside:Before render',
648 'Text:Inside:After render',
649 'Text:Outside render',
650 + 'Text:Inside:Before create insertion',
651 + 'Text:Inside:After create insertion',
652 + 'Text:Outside create insertion',
653 'Text:Inside:Before create layout',
654 'Text:Inside:After create layout',
655 'Text:Outside create layout',
@@ -652,6 +682,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
682 'Text:Outside render',
683 'Text:Inside:Before destroy layout',
684 'Text:Inside:After destroy layout',
685 + 'Text:Fallback create insertion',
686 'Text:Fallback create layout',
687 ]);
688 await waitForAll([
@@ -683,6 +714,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
714 'Text:Inside:Before render',
715 'AsyncText:Async render',
716 'Text:Inside:After render',
717 + 'Text:Fallback destroy insertion',
718 'Text:Fallback destroy layout',
719 'Text:Inside:Before create layout',
720 'AsyncText:Async create layout',
@@ -704,9 +736,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
736 });
737 assertLog([
738 'App destroy layout',
739 + 'Text:Inside:Before destroy insertion',
740 'Text:Inside:Before destroy layout',
741 'AsyncText:Async destroy layout',
742 + 'Text:Inside:After destroy insertion',
743 'Text:Inside:After destroy layout',
744 + 'Text:Outside destroy insertion',
745 'Text:Outside destroy layout',
746 'App destroy passive',
747 'Text:Inside:Before destroy passive',
@@ -893,6 +928,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
928 'App render',
929 'Text:Outer render',
930 'Text:Inner render',
931 + 'Text:Inner create insertion',
932 + 'Text:Outer create insertion',
933 'Text:Inner create layout',
934 'Text:Outer create layout',
935 'App create layout',
@@ -919,6 +956,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
956 'Text:Fallback render',
957 'Text:Outer destroy layout',
958 'Text:Inner destroy layout',
959 + 'Text:Fallback create insertion',
960 'Text:Fallback create layout',
961 ]);
962 await waitForAll([
@@ -946,6 +984,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
984 'AsyncText:Async render',
985 'Text:Outer render',
986 'Text:Inner render',
987 + 'Text:Fallback destroy insertion',
988 'Text:Fallback destroy layout',
989 'AsyncText:Async create layout',
990 'Text:Inner create layout',
@@ -968,7 +1007,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
1007 assertLog([
1008 'App destroy layout',
1009 'AsyncText:Async destroy layout',
1010 + 'Text:Outer destroy insertion',
1011 'Text:Outer destroy layout',
1012 + 'Text:Inner destroy insertion',
1013 'Text:Inner destroy layout',
1014 'App destroy passive',
1015 'AsyncText:Async destroy passive',
@@ -1013,6 +1054,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1054 'App render',
1055 'Text:Outer render',
1056 'Text:MemoizedInner render',
1057 + 'Text:MemoizedInner create insertion',
1058 + 'Text:Outer create insertion',
1059 'Text:MemoizedInner create layout',
1060 'Text:Outer create layout',
1061 'App create layout',
@@ -1040,6 +1083,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1083 'Text:Fallback render',
1084 'Text:Outer destroy layout',
1085 'Text:MemoizedInner destroy layout',
1086 + 'Text:Fallback create insertion',
1087 'Text:Fallback create layout',
1088 ]);
1089 await waitForAll([
@@ -1066,6 +1110,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1110 assertLog([
1111 'AsyncText:Async render',
1112 'Text:Outer render',
1113 + 'Text:Fallback destroy insertion',
1114 'Text:Fallback destroy layout',
1115 'AsyncText:Async create layout',
1116 'Text:MemoizedInner create layout',
@@ -1088,7 +1133,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
1133 assertLog([
1134 'App destroy layout',
1135 'AsyncText:Async destroy layout',
1136 + 'Text:Outer destroy insertion',
1137 'Text:Outer destroy layout',
1138 + 'Text:MemoizedInner destroy insertion',
1139 'Text:MemoizedInner destroy layout',
1140 'App destroy passive',
1141 'AsyncText:Async destroy passive',
@@ -1119,6 +1166,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1166 assertLog([
1167 'Text:Outer render',
1168 'Text:Inner render',
1169 + 'Text:Outer create insertion',
1170 + 'Text:Inner create insertion',
1171 'Text:Outer create layout',
1172 'Text:Inner create layout',
1173 'Text:Outer create passive',
@@ -1143,6 +1192,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1192 'Suspend:InnerAsync_1',
1193 'Text:InnerFallback render',
1194 'Text:Inner destroy layout',
1195 + 'Text:InnerFallback create insertion',
1196 'Text:InnerFallback create layout',
1197 'Text:InnerFallback create passive',
1198
@@ -1175,6 +1225,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1225 'Text:OuterFallback render',
1226 'Text:Outer destroy layout',
1227 'Text:InnerFallback destroy layout',
1228 + 'Text:OuterFallback create insertion',
1229 'Text:OuterFallback create layout',
1230 'Text:OuterFallback create passive',
1231
@@ -1267,7 +1318,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1318 'Text:Inner render',
1319 'Suspend:InnerAsync_2',
1320 'Text:InnerFallback render',
1270 -
1321 + 'Text:OuterFallback destroy insertion',
1322 'Text:OuterFallback destroy layout',
1323 'Text:Outer create layout',
1324 'AsyncText:OuterAsync_1 create layout',
@@ -1295,6 +1346,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1346 assertLog([
1347 'Text:Inner render',
1348 'AsyncText:InnerAsync_2 render',
1349 + 'Text:InnerFallback destroy insertion',
1350 'Text:InnerFallback destroy layout',
1351 'Text:Inner create layout',
1352 'AsyncText:InnerAsync_2 create layout',
@@ -1327,6 +1379,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1379 'AsyncText:OuterAsync_1 destroy layout',
1380 'Text:Inner destroy layout',
1381 'AsyncText:InnerAsync_2 destroy layout',
1382 + 'Text:OuterFallback create insertion',
1383 'Text:OuterFallback create layout',
1384 'Text:OuterFallback create passive',
1385
@@ -1358,6 +1411,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1411 'AsyncText:OuterAsync_2 render',
1412 'Text:Inner render',
1413 'AsyncText:InnerAsync_2 render',
1414 + 'Text:OuterFallback destroy insertion',
1415 'Text:OuterFallback destroy layout',
1416 'Text:Outer create layout',
1417 'AsyncText:OuterAsync_2 create layout',
@@ -1397,6 +1451,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1451 assertLog([
1452 'Text:Outer render',
1453 'Text:Inner render',
1454 + 'Text:Outer create insertion',
1455 + 'Text:Inner create insertion',
1456 'Text:Outer create layout',
1457 'Text:Inner create layout',
1458 'Text:Outer create passive',
@@ -1421,6 +1477,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1477 'Suspend:InnerAsync_1',
1478 'Text:InnerFallback render',
1479 'Text:Inner destroy layout',
1480 + 'Text:InnerFallback create insertion',
1481 'Text:InnerFallback create layout',
1482 'Text:InnerFallback create passive',
1483
@@ -1452,6 +1509,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1509 'Text:OuterFallback render',
1510 'Text:Outer destroy layout',
1511 'Text:InnerFallback destroy layout',
1512 + 'Text:OuterFallback create insertion',
1513 'Text:OuterFallback create layout',
1514 'Text:OuterFallback create passive',
1515
@@ -1484,7 +1542,11 @@ describe('ReactSuspenseEffectsSemantics', () => {
1542 'AsyncText:OuterAsync_1 render',
1543 'Text:Inner render',
1544 'AsyncText:InnerAsync_1 render',
1545 + 'Text:OuterFallback destroy insertion',
1546 'Text:OuterFallback destroy layout',
1547 + ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
1548 + ? ['Text:InnerFallback destroy insertion']
1549 + : []),
1550 'Text:Outer create layout',
1551 'AsyncText:OuterAsync_1 create layout',
1552 'Text:Inner create layout',
@@ -1534,6 +1596,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1596 assertLog([
1597 'Text:Inside render',
1598 'Text:Outside render',
1599 + 'Text:Inside create insertion',
1600 + 'Text:Outside create insertion',
1601 'Text:Inside create layout',
1602 'Text:Outside create layout',
1603 'Text:Inside create passive',
@@ -1558,6 +1622,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1622 'Text:Fallback:Outside render',
1623 'Text:Outside render',
1624 'Text:Inside destroy layout',
1625 + 'Text:Fallback:Inside create insertion',
1626 + 'Text:Fallback:Outside create insertion',
1627 'Text:Fallback:Inside create layout',
1628 'Text:Fallback:Outside create layout',
1629 ]);
@@ -1596,6 +1662,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1662 'Text:Fallback:Outside render',
1663 'Text:Outside render',
1664 'Text:Fallback:Inside destroy layout',
1665 + 'Text:Fallback:Fallback create insertion',
1666 'Text:Fallback:Fallback create layout',
1667 ]);
1668 await waitForAll([
@@ -1629,7 +1696,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
1696 assertLog([
1697 'Text:Inside render',
1698 'AsyncText:OutsideAsync render',
1699 + ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
1700 + ? ['Text:Fallback:Inside destroy insertion']
1701 + : []),
1702 + 'Text:Fallback:Fallback destroy insertion',
1703 'Text:Fallback:Fallback destroy layout',
1704 + 'Text:Fallback:Outside destroy insertion',
1705 'Text:Fallback:Outside destroy layout',
1706 'Text:Inside create layout',
1707 'AsyncText:OutsideAsync create layout',
@@ -1677,6 +1749,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1749 assertLog([
1750 'Text:Inside render',
1751 'Text:Outside render',
1752 + 'Text:Inside create insertion',
1753 + 'Text:Outside create insertion',
1754 'Text:Inside create layout',
1755 'Text:Outside create layout',
1756 'Text:Inside create passive',
@@ -1707,6 +1781,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1781 'Text:Fallback:Outside render',
1782 'Text:Outside render',
1783 'Text:Inside destroy layout',
1784 + 'Text:Fallback:Fallback create insertion',
1785 + 'Text:Fallback:Outside create insertion',
1786 'Text:Fallback:Fallback create layout',
1787 'Text:Fallback:Outside create layout',
1788 'Text:Fallback:Fallback create passive',
@@ -1737,7 +1813,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
1813 assertLog([
1814 'Text:Fallback:Inside render',
1815 'AsyncText:FallbackAsync render',
1816 + 'Text:Fallback:Fallback destroy insertion',
1817 'Text:Fallback:Fallback destroy layout',
1818 + 'Text:Fallback:Inside create insertion',
1819 'Text:Fallback:Inside create layout',
1820 'AsyncText:FallbackAsync create layout',
1821 'Text:Fallback:Fallback destroy passive',
@@ -1761,8 +1839,10 @@ describe('ReactSuspenseEffectsSemantics', () => {
1839 assertLog([
1840 'Text:Inside render',
1841 'AsyncText:OutsideAsync render',
1842 + 'Text:Fallback:Inside destroy insertion',
1843 'Text:Fallback:Inside destroy layout',
1844 'AsyncText:FallbackAsync destroy layout',
1845 + 'Text:Fallback:Outside destroy insertion',
1846 'Text:Fallback:Outside destroy layout',
1847 'Text:Inside create layout',
1848 'AsyncText:OutsideAsync create layout',
@@ -1807,6 +1887,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
1887 assertLog([
1888 'Text:Inside render',
1889 'Text:Outside render',
1890 + 'Text:Inside create insertion',
1891 + 'Text:Outside create insertion',
1892 'Text:Inside create layout',
1893 'Text:Outside create layout',
1894 'Text:Inside create passive',
@@ -1828,6 +1910,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1910 'Text:Fallback render',
1911 'Text:Outside render',
1912 'Text:Inside destroy layout',
1913 + 'Text:Fallback create insertion',
1914 'Text:Fallback create layout',
1915 ]);
1916 await waitForAll([
@@ -1850,6 +1933,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
1933 });
1934 assertLog([
1935 'Text:Inside render',
1936 + 'Text:Fallback destroy insertion',
1937 'Text:Fallback destroy layout',
1938 'Text:Inside create layout',
1939 'Text:Fallback destroy passive',
@@ -1916,6 +2000,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
2000 'ThrowsInDidMount render',
2001 'Text:Inside render',
2002 'Text:Outside render',
2003 + 'Text:Inside create insertion',
2004 + 'Text:Outside create insertion',
2005 'ThrowsInDidMount componentDidMount',
2006 'Text:Inside create layout',
2007 'Text:Outside create layout',
@@ -1949,6 +2035,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2035 'Text:Outside render',
2036 'ThrowsInDidMount componentWillUnmount',
2037 'Text:Inside destroy layout',
2038 + 'Text:Fallback create insertion',
2039 'Text:Fallback create layout',
2040 'Text:Fallback create passive',
2041
@@ -1974,6 +2061,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2061 'AsyncText:Async render',
2062 'ThrowsInDidMount render',
2063 'Text:Inside render',
2064 + 'Text:Fallback destroy insertion',
2065 'Text:Fallback destroy layout',
2066 'AsyncText:Async create layout',
2067
@@ -1986,11 +2074,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
2074 'Text:Fallback destroy passive',
2075 'AsyncText:Async create passive',
2076
1989 - // Destroy layout and passive effects in the errored tree.
2077 + // Destroy insertion, layout, and passive effects in the errored tree.
2078 'App destroy layout',
2079 'AsyncText:Async destroy layout',
2080 'ThrowsInDidMount componentWillUnmount',
2081 + 'Text:Inside destroy insertion',
2082 'Text:Inside destroy layout',
2083 + 'Text:Outside destroy insertion',
2084 'Text:Outside destroy layout',
2085 'AsyncText:Async destroy passive',
2086 'Text:Inside destroy passive',
@@ -1999,6 +2089,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2089 // Render fallback
2090 'ErrorBoundary render: catch',
2091 'Text:Error render',
2092 + 'Text:Error create insertion',
2093 'Text:Error create layout',
2094 'Text:Error create passive',
2095 ]);
@@ -2054,6 +2145,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
2145 'ThrowsInWillUnmount render',
2146 'Text:Inside render',
2147 'Text:Outside render',
2148 + 'Text:Inside create insertion',
2149 + 'Text:Outside create insertion',
2150 'ThrowsInWillUnmount componentDidMount',
2151 'Text:Inside create layout',
2152 'Text:Outside create layout',
@@ -2092,12 +2185,18 @@ describe('ReactSuspenseEffectsSemantics', () => {
2185 'Text:Inside destroy layout',
2186
2187 // Finish the in-progress commit
2188 + 'Text:Fallback create insertion',
2189 'Text:Fallback create layout',
2190 'Text:Fallback create passive',
2191
2192 // Destroy layout and passive effects in the errored tree.
2193 'App destroy layout',
2194 + ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
2195 + ? ['Text:Inside destroy insertion']
2196 + : []),
2197 + 'Text:Fallback destroy insertion',
2198 'Text:Fallback destroy layout',
2199 + 'Text:Outside destroy insertion',
2200 'Text:Outside destroy layout',
2201 'Text:Inside destroy passive',
2202 'Text:Fallback destroy passive',
@@ -2106,6 +2205,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2205 // Render fallback
2206 'ErrorBoundary render: catch',
2207 'Text:Error render',
2208 + 'Text:Error create insertion',
2209 'Text:Error create layout',
2210 'Text:Error create passive',
2211 ]);
@@ -2163,6 +2263,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
2263 'ThrowsInLayoutEffect render',
2264 'Text:Inside render',
2265 'Text:Outside render',
2266 + 'Text:Inside create insertion',
2267 + 'Text:Outside create insertion',
2268 'ThrowsInLayoutEffect useLayoutEffect create',
2269 'Text:Inside create layout',
2270 'Text:Outside create layout',
@@ -2196,6 +2298,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2298 'Text:Outside render',
2299 'ThrowsInLayoutEffect useLayoutEffect destroy',
2300 'Text:Inside destroy layout',
2301 + 'Text:Fallback create insertion',
2302 'Text:Fallback create layout',
2303 'Text:Fallback create passive',
2304
@@ -2226,6 +2329,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2329 'ThrowsInLayoutEffect render',
2330 'Text:Inside render',
2331
2332 + 'Text:Fallback destroy insertion',
2333 'Text:Fallback destroy layout',
2334
2335 // Even though an error was thrown in useLayoutEffect,
@@ -2241,7 +2345,9 @@ describe('ReactSuspenseEffectsSemantics', () => {
2345 // Destroy layout and passive effects in the errored tree.
2346 'App destroy layout',
2347 'AsyncText:Async destroy layout',
2348 + 'Text:Inside destroy insertion',
2349 'Text:Inside destroy layout',
2350 + 'Text:Outside destroy insertion',
2351 'Text:Outside destroy layout',
2352 'AsyncText:Async destroy passive',
2353 'Text:Inside destroy passive',
@@ -2250,6 +2356,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2356 // Render fallback
2357 'ErrorBoundary render: catch',
2358 'Text:Error render',
2359 + 'Text:Error create insertion',
2360 'Text:Error create layout',
2361 'Text:Error create passive',
2362 ]);
@@ -2305,6 +2412,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
2412 'ThrowsInLayoutEffectDestroy render',
2413 'Text:Inside render',
2414 'Text:Outside render',
2415 + 'Text:Inside create insertion',
2416 + 'Text:Outside create insertion',
2417 'ThrowsInLayoutEffectDestroy useLayoutEffect create',
2418 'Text:Inside create layout',
2419 'Text:Outside create layout',
@@ -2343,12 +2452,18 @@ describe('ReactSuspenseEffectsSemantics', () => {
2452 'Text:Inside destroy layout',
2453
2454 // Finish the in-progress commit
2455 + 'Text:Fallback create insertion',
2456 'Text:Fallback create layout',
2457 'Text:Fallback create passive',
2458
2459 // Destroy layout and passive effects in the errored tree.
2460 'App destroy layout',
2461 + ...(gate(flags => flags.enableHiddenSubtreeInsertionEffectCleanup)
2462 + ? ['Text:Inside destroy insertion']
2463 + : []),
2464 + 'Text:Fallback destroy insertion',
2465 'Text:Fallback destroy layout',
2466 + 'Text:Outside destroy insertion',
2467 'Text:Outside destroy layout',
2468 'Text:Inside destroy passive',
2469 'Text:Fallback destroy passive',
@@ -2357,6 +2472,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2472 // Render fallback
2473 'ErrorBoundary render: catch',
2474 'Text:Error render',
2475 + 'Text:Error create insertion',
2476 'Text:Error create layout',
2477 'Text:Error create passive',
2478 ]);
@@ -2402,6 +2518,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2518 assertLog([
2519 'Text:Function render',
2520 'ClassText:Class render',
2521 + 'Text:Function create insertion',
2522 'Text:Function create layout',
2523 'ClassText:Class componentDidMount',
2524 'Text:Function create passive',
@@ -2503,6 +2620,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2620 ReactNoop.render(null);
2621 });
2622 assertLog([
2623 + 'Text:Function destroy insertion',
2624 'Text:Function destroy layout',
2625 'AsyncText:Async_1 destroy layout',
2626 'AsyncText:Async_2 destroy layout',
@@ -2562,6 +2680,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2680 'Text:Function render',
2681 'Suspender "null" render',
2682 'ClassText:Class render',
2683 + 'Text:Function create insertion',
2684 'Text:Function create layout',
2685 'ClassText:Class componentDidMount',
2686 'Text:Function create passive',
@@ -2657,6 +2776,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2776 ReactNoop.render(null);
2777 });
2778 assertLog([
2779 + 'Text:Function destroy insertion',
2780 'Text:Function destroy layout',
2781 'ClassText:Class componentWillUnmount',
2782 'Text:Function destroy passive',
@@ -2774,6 +2894,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2894 'ClassComponent:refCallback render',
2895 'RefCheckerInner:refCallback render',
2896 'Text:Fallback render',
2897 + 'Text:Fallback create insertion',
2898 'Text:Fallback create layout',
2899 'Text:Fallback create passive',
2900 ]);
@@ -2785,6 +2906,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2906 });
2907 assertLog([
2908 'AsyncText:Async render',
2909 + 'Text:Fallback destroy insertion',
2910 'Text:Fallback destroy layout',
2911 'AsyncText:Async create layout',
2912 'Text:Fallback destroy passive',
@@ -2852,6 +2974,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
2974 'RefCheckerInner:refObject destroy layout ref? false',
2975 'RefCheckerOuter refCallback value? false',
2976 'RefCheckerInner:refCallback destroy layout ref? false',
2977 + 'Text:Fallback create insertion',
2978 'Text:Fallback create layout',
2979 'Text:Fallback create passive',
2980
@@ -2881,6 +3004,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3004 'RefCheckerOuter render',
3005 'RefCheckerInner:refObject render',
3006 'RefCheckerInner:refCallback render',
3007 + 'Text:Fallback destroy insertion',
3008 'Text:Fallback destroy layout',
3009 'AsyncText:Async create layout',
3010 'RefCheckerInner:refObject create layout ref? false',
@@ -2962,6 +3086,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3086 'RefCheckerInner:refObject destroy layout ref? false',
3087 'RefCheckerOuter refCallback value? false',
3088 'RefCheckerInner:refCallback destroy layout ref? false',
3089 + 'Text:Fallback create insertion',
3090 'Text:Fallback create layout',
3091 'Text:Fallback create passive',
3092
@@ -2989,6 +3114,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3114 'RefCheckerInner:refObject render',
3115 'ClassComponent:refCallback render',
3116 'RefCheckerInner:refCallback render',
3117 + 'Text:Fallback destroy insertion',
3118 'Text:Fallback destroy layout',
3119 'AsyncText:Async create layout',
3120 'RefCheckerInner:refObject create layout ref? false',
@@ -3070,6 +3196,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3196 'RefCheckerInner:refObject destroy layout ref? false',
3197 'RefCheckerOuter refCallback value? false',
3198 'RefCheckerInner:refCallback destroy layout ref? false',
3199 + 'Text:Fallback create insertion',
3200 'Text:Fallback create layout',
3201 'Text:Fallback create passive',
3202
@@ -3097,6 +3224,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3224 'RefCheckerInner:refObject render',
3225 'FunctionComponent render',
3226 'RefCheckerInner:refCallback render',
3227 + 'Text:Fallback destroy insertion',
3228 'Text:Fallback destroy layout',
3229 'AsyncText:Async create layout',
3230 'RefCheckerInner:refObject create layout ref? false',
@@ -3180,6 +3308,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3308 'Suspend:Async',
3309 'Text:Fallback render',
3310 'RefChecker destroy layout ref? true',
3311 + 'Text:Fallback create insertion',
3312 'Text:Fallback create layout',
3313 'Text:Fallback create passive',
3314
@@ -3196,6 +3325,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3325 assertLog([
3326 'AsyncText:Async render',
3327 'RefChecker render',
3328 + 'Text:Fallback destroy insertion',
3329 'Text:Fallback destroy layout',
3330 'AsyncText:Async create layout',
3331 'RefChecker create layout ref? true',
@@ -3265,6 +3395,8 @@ describe('ReactSuspenseEffectsSemantics', () => {
3395 'ThrowsInRefCallback render',
3396 'Text:Inside render',
3397 'Text:Outside render',
3398 + 'Text:Inside create insertion',
3399 + 'Text:Outside create insertion',
3400 'ThrowsInRefCallback refCallback ref? true',
3401 'Text:Inside create layout',
3402 'Text:Outside create layout',
@@ -3298,6 +3430,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3430 'Text:Outside render',
3431 'ThrowsInRefCallback refCallback ref? false',
3432 'Text:Inside destroy layout',
3433 + 'Text:Fallback create insertion',
3434 'Text:Fallback create layout',
3435 'Text:Fallback create passive',
3436
@@ -3330,6 +3463,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3463
3464 // Even though an error was thrown in refCallback,
3465 // subsequent layout effects should still be created.
3466 + 'Text:Fallback destroy insertion',
3467 'Text:Fallback destroy layout',
3468 'AsyncText:Async create layout',
3469 'ThrowsInRefCallback refCallback ref? true',
@@ -3339,11 +3473,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
3473 'Text:Fallback destroy passive',
3474 'AsyncText:Async create passive',
3475
3342 - // Destroy layout and passive effects in the errored tree.
3476 + // Destroy insertion, layout, and passive effects in the errored tree.
3477 'App destroy layout',
3478 'AsyncText:Async destroy layout',
3479 'ThrowsInRefCallback refCallback ref? false',
3480 + 'Text:Inside destroy insertion',
3481 'Text:Inside destroy layout',
3482 + 'Text:Outside destroy insertion',
3483 'Text:Outside destroy layout',
3484 'AsyncText:Async destroy passive',
3485 'Text:Inside destroy passive',
@@ -3352,6 +3488,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
3488 // Render fallback
3489 'ErrorBoundary render: catch',
3490 'Text:Error render',
3491 + 'Text:Error create insertion',
3492 'Text:Error create layout',
3493 'Text:Error create passive',
3494 ]);
packages/shared/ReactFeatureFlags.js
+5
@@ -172,6 +172,11 @@ export const transitionLaneExpirationMs = 5000;
172 // Renames the internal symbol for elements since they have changed signature/constructor
173 export const renameElementSymbol = true;
174
175 +/**
176 + * Enables a fix to run insertion effect cleanup on hidden subtrees.
177 + */
178 +export const enableHiddenSubtreeInsertionEffectCleanup = false;
179 +
180 /**
181 * Removes legacy style context defined using static `contextTypes` and consumed with static `childContextTypes`.
182 */
packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
+1
@@ -20,6 +20,7 @@
20 export const alwaysThrottleRetries = __VARIANT__;
21 export const enableAddPropertiesFastPath = __VARIANT__;
22 export const enableObjectFiber = __VARIANT__;
23 +export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__;
24 export const enablePersistedModeClonedFlag = __VARIANT__;
25 export const enableShallowPropDiffing = __VARIANT__;
26 export const passChildrenWhenCloningPersistedNodes = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -22,6 +22,7 @@ export const {
22 alwaysThrottleRetries,
23 enableAddPropertiesFastPath,
24 enableFabricCompleteRootInCommitPhase,
25 + enableHiddenSubtreeInsertionEffectCleanup,
26 enableObjectFiber,
27 enablePersistedModeClonedFlag,
28 enableShallowPropDiffing,
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -50,6 +50,7 @@ export const enableFizzExternalRuntime = true;
50 export const enableFlightReadableStream = true;
51 export const enableGetInspectorDataForInstanceInProduction = false;
52 export const enableHalt = false;
53 +export const enableHiddenSubtreeInsertionEffectCleanup = false;
54 export const enableInfiniteRenderLoopDetection = true;
55 export const enableLazyContextPropagation = false;
56 export const enableContextProfiling = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -46,6 +46,7 @@ export const enableLegacyFBSupport = false;
46 export const enableFilterEmptyStringAttributesDOM = true;
47 export const enableGetInspectorDataForInstanceInProduction = false;
48 export const enableFabricCompleteRootInCommitPhase = false;
49 +export const enableHiddenSubtreeInsertionEffectCleanup = false;
50
51 export const enableRetryLaneExpiration = false;
52 export const retryLaneExpirationMs = 5000;
packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
+1
@@ -44,6 +44,7 @@ export const enableHalt = false;
44 export const enableInfiniteRenderLoopDetection = true;
45 export const enableLazyContextPropagation = false;
46 export const enableContextProfiling = false;
47 +export const enableHiddenSubtreeInsertionEffectCleanup = true;
48 export const enableLegacyCache = false;
49 export const enableLegacyFBSupport = false;
50 export const enableLegacyHidden = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -49,6 +49,7 @@ export const enableFilterEmptyStringAttributesDOM = true;
49 export const enableGetInspectorDataForInstanceInProduction = false;
50 export const enableRenderableContext = false;
51 export const enableFabricCompleteRootInCommitPhase = false;
52 +export const enableHiddenSubtreeInsertionEffectCleanup = true;
53
54 export const enableRetryLaneExpiration = false;
55 export const retryLaneExpirationMs = 5000;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+1
@@ -21,6 +21,7 @@ export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
21 export const enableAddPropertiesFastPath = __VARIANT__;
22 export const enableDeferRootSchedulingToMicrotask = __VARIANT__;
23 export const enableDO_NOT_USE_disableStrictPassiveEffect = __VARIANT__;
24 +export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__;
25 export const enableNoCloningMemoCache = __VARIANT__;
26 export const enableObjectFiber = __VARIANT__;
27 export const enableRenderableContext = __VARIANT__;
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -30,6 +30,7 @@ export const {
30 enableRetryLaneExpiration,
31 enableTransitionTracing,
32 enableTrustedTypesIntegration,
33 + enableHiddenSubtreeInsertionEffectCleanup,
34 favorSafetyOverHydrationPerf,
35 renameElementSymbol,
36 retryLaneExpirationMs,