Remove enablePersistentOffscreenHostContainer flag (#24460)
This was a Fabric-related experiment that we ended up not shipping.
Andrew Clark committed
Apr 28, 2022 at 15:05 UTC
ce13860281f833de8a3296b7a3dad9caced102e9
24 files changed
+25
-688
packages/react-native-renderer/src/ReactFabricHostConfig.js
-32
@@ -7,7 +7,6 @@
7
* @flow
8
*/
9
10
-import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
10
import type {ElementRef} from 'react';
11
import type {
12
HostComponent,
@@ -545,37 +544,6 @@ export function cloneInstance(
544
};
545
}
546
548
-// TODO: These two methods should be replaced with `createOffscreenInstance` and
549
-// `cloneOffscreenInstance`. I did it this way for now because the offscreen
550
-// instance is stored on an extra HostComponent fiber instead of the
551
-// OffscreenComponent fiber, and I didn't want to add an extra check to the
552
-// generic HostComponent path. Instead we should use the OffscreenComponent
553
-// fiber, but currently Fabric expects a 1:1 correspondence between Fabric
554
-// instances and host fibers, so I'm leaving this optimization for later once
555
-// we can confirm this won't break any downstream expectations.
556
-export function getOffscreenContainerType(): string {
557
- return 'RCTView';
558
-}
559
-
560
-export function getOffscreenContainerProps(
561
- mode: OffscreenMode,
562
- children: ReactNodeList,
563
-): Props {
564
- if (mode === 'hidden') {
565
- return {
566
- children,
567
- style: {display: 'none'},
568
- };
569
- } else {
570
- return {
571
- children,
572
- style: {
573
- flex: 1,
574
- },
575
- };
576
- }
577
-}
578
-
547
export function cloneHiddenInstance(
548
instance: Instance,
549
type: string,
packages/react-noop-renderer/src/createReactNoop.js
+3
-176
@@ -19,7 +19,7 @@ import type {
19
TransitionTracingCallbacks,
20
} from 'react-reconciler/src/ReactInternalTypes';
21
import type {UpdateQueue} from 'react-reconciler/src/ReactUpdateQueue';
22
-import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
22
+import type {ReactNodeList} from 'shared/ReactTypes';
23
import type {RootTag} from 'react-reconciler/src/ReactRootTags';
24
25
import * as Scheduler from 'scheduler/unstable_mock';
@@ -595,20 +595,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
595
container.children = newChildren;
596
},
597
598
- getOffscreenContainerType(): string {
599
- return 'offscreen';
600
- },
601
-
602
- getOffscreenContainerProps(
603
- mode: OffscreenMode,
604
- children: ReactNodeList,
605
- ): Props {
606
- return {
607
- hidden: mode === 'hidden',
608
- children,
609
- };
610
- },
611
-
598
cloneHiddenInstance(
599
instance: Instance,
600
type: string,
@@ -721,9 +707,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
707
708
function getChildren(root) {
709
if (root) {
724
- return useMutation
725
- ? root.children
726
- : removeOffscreenContainersFromChildren(root.children, false);
710
+ return root.children;
711
} else {
712
return null;
713
}
@@ -731,169 +715,12 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
715
716
function getPendingChildren(root) {
717
if (root) {
734
- return useMutation
735
- ? root.children
736
- : removeOffscreenContainersFromChildren(root.pendingChildren, false);
718
+ return root.children;
719
} else {
720
return null;
721
}
722
}
723
742
- function removeOffscreenContainersFromChildren(children, hideNearestNode) {
743
- // Mutation mode and persistent mode have different outputs for Offscreen
744
- // and Suspense trees. Persistent mode adds an additional host node wrapper,
745
- // whereas mutation mode does not.
746
- //
747
- // This function removes the offscreen host wrappers so that the output is
748
- // consistent. If the offscreen node is hidden, it transfers the hiddenness
749
- // to the child nodes, to mimic how it works in mutation mode. That way our
750
- // tests don't have to fork tree assertions.
751
- //
752
- // So, it takes a tree that looks like this:
753
- //
754
- // <offscreen hidden={true}>
755
- // <span>A</span>
756
- // <span>B</span>
757
- // </offscren>
758
- //
759
- // And turns it into this:
760
- //
761
- // <span hidden={true}>A</span>
762
- // <span hidden={true}>B</span>
763
- //
764
- // We don't mutate the original tree, but instead return a copy.
765
- //
766
- // This function is only used by our test assertions, via the `getChildren`
767
- // and `getChildrenAsJSX` methods.
768
- let didClone = false;
769
- const newChildren = [];
770
- for (let i = 0; i < children.length; i++) {
771
- const child = children[i];
772
- const innerChildren = child.children;
773
- if (innerChildren !== undefined) {
774
- // This is a host instance instance
775
- const instance: Instance = (child: any);
776
- if (instance.type === 'offscreen') {
777
- // This is an offscreen wrapper instance. Remove it from the tree
778
- // and recursively return its children, as if it were a fragment.
779
- didClone = true;
780
- if (instance.text !== null) {
781
- // If this offscreen tree contains only text, we replace it with
782
- // a text child. Related to `shouldReplaceTextContent` feature.
783
- const offscreenTextInstance: TextInstance = {
784
- text: instance.text,
785
- id: instanceCounter++,
786
- parent: instance.parent,
787
- hidden: hideNearestNode || instance.hidden,
788
- context: instance.context,
789
- };
790
- // Hide from unit tests
791
- Object.defineProperty(offscreenTextInstance, 'id', {
792
- value: offscreenTextInstance.id,
793
- enumerable: false,
794
- });
795
- Object.defineProperty(offscreenTextInstance, 'parent', {
796
- value: offscreenTextInstance.parent,
797
- enumerable: false,
798
- });
799
- Object.defineProperty(offscreenTextInstance, 'context', {
800
- value: offscreenTextInstance.context,
801
- enumerable: false,
802
- });
803
- newChildren.push(offscreenTextInstance);
804
- } else {
805
- // Skip the offscreen node and replace it with its children
806
- const offscreenChildren = removeOffscreenContainersFromChildren(
807
- innerChildren,
808
- hideNearestNode || instance.hidden,
809
- );
810
- newChildren.push.apply(newChildren, offscreenChildren);
811
- }
812
- } else {
813
- // This is a regular (non-offscreen) instance. If the nearest
814
- // offscreen boundary is hidden, hide this node.
815
- const hidden = hideNearestNode ? true : instance.hidden;
816
- const clonedChildren = removeOffscreenContainersFromChildren(
817
- instance.children,
818
- // We never need to hide the children of this node, since if we're
819
- // inside a hidden tree, then the hidden style will be applied to
820
- // this node.
821
- false,
822
- );
823
- if (
824
- clonedChildren === instance.children &&
825
- hidden === instance.hidden
826
- ) {
827
- // No changes. Reuse the original instance without cloning.
828
- newChildren.push(instance);
829
- } else {
830
- didClone = true;
831
- const clone: Instance = {
832
- id: instance.id,
833
- type: instance.type,
834
- parent: instance.parent,
835
- children: clonedChildren,
836
- text: instance.text,
837
- prop: instance.prop,
838
- hidden: hideNearestNode ? true : instance.hidden,
839
- context: instance.context,
840
- };
841
- Object.defineProperty(clone, 'id', {
842
- value: clone.id,
843
- enumerable: false,
844
- });
845
- Object.defineProperty(clone, 'parent', {
846
- value: clone.parent,
847
- enumerable: false,
848
- });
849
- Object.defineProperty(clone, 'text', {
850
- value: clone.text,
851
- enumerable: false,
852
- });
853
- Object.defineProperty(clone, 'context', {
854
- value: clone.context,
855
- enumerable: false,
856
- });
857
- newChildren.push(clone);
858
- }
859
- }
860
- } else {
861
- // This is a text instance
862
- const textInstance: TextInstance = (child: any);
863
- if (hideNearestNode) {
864
- didClone = true;
865
- const clone = {
866
- text: textInstance.text,
867
- id: textInstance.id,
868
- parent: textInstance.parent,
869
- hidden: textInstance.hidden || hideNearestNode,
870
- context: textInstance.context,
871
- };
872
- Object.defineProperty(clone, 'id', {
873
- value: clone.id,
874
- enumerable: false,
875
- });
876
- Object.defineProperty(clone, 'parent', {
877
- value: clone.parent,
878
- enumerable: false,
879
- });
880
- Object.defineProperty(clone, 'context', {
881
- value: clone.context,
882
- enumerable: false,
883
- });
884
-
885
- newChildren.push(clone);
886
- } else {
887
- newChildren.push(textInstance);
888
- }
889
- }
890
- }
891
- // There are some tests that assume reference equality, so preserve it
892
- // when possible. Alternatively, we could update the tests to compare the
893
- // ids instead.
894
- return didClone ? newChildren : children;
895
- }
896
-
724
function getChildrenAsJSX(root) {
725
const children = childToJSX(getChildren(root), null);
726
if (children === null) {
packages/react-reconciler/src/ReactFiber.new.js
+1
-24
@@ -14,7 +14,7 @@ import type {RootTag} from './ReactRootTags';
14
import type {WorkTag} from './ReactWorkTags';
15
import type {TypeOfMode} from './ReactTypeOfMode';
16
import type {Lanes} from './ReactFiberLane.new';
17
-import type {SuspenseInstance, Props} from './ReactFiberHostConfig';
17
+import type {SuspenseInstance} from './ReactFiberHostConfig';
18
import type {
19
OffscreenProps,
20
OffscreenInstance,
@@ -32,10 +32,6 @@ import {
32
enableTransitionTracing,
33
enableDebugTracing,
34
} from 'shared/ReactFeatureFlags';
35
-import {
36
- supportsPersistence,
37
- getOffscreenContainerType,
38
-} from './ReactFiberHostConfig';
35
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
36
import {ConcurrentRoot} from './ReactRootTags';
37
import {
@@ -605,25 +601,6 @@ export function createFiberFromTypeAndProps(
601
return fiber;
602
}
603
608
-export function createOffscreenHostContainerFiber(
609
- props: Props,
610
- fiberMode: TypeOfMode,
611
- lanes: Lanes,
612
- key: null | string,
613
-): Fiber {
614
- if (supportsPersistence) {
615
- const type = getOffscreenContainerType();
616
- const fiber = createFiber(HostComponent, props, key, fiberMode);
617
- fiber.elementType = type;
618
- fiber.type = type;
619
- fiber.lanes = lanes;
620
- return fiber;
621
- } else {
622
- // Only implemented in persistent mode
623
- throw new Error('Not implemented.');
624
- }
625
-}
626
-
604
export function createFiberFromElement(
605
element: ReactElement,
606
mode: TypeOfMode,
packages/react-reconciler/src/ReactFiber.old.js
+1
-24
@@ -14,7 +14,7 @@ import type {RootTag} from './ReactRootTags';
14
import type {WorkTag} from './ReactWorkTags';
15
import type {TypeOfMode} from './ReactTypeOfMode';
16
import type {Lanes} from './ReactFiberLane.old';
17
-import type {SuspenseInstance, Props} from './ReactFiberHostConfig';
17
+import type {SuspenseInstance} from './ReactFiberHostConfig';
18
import type {
19
OffscreenProps,
20
OffscreenInstance,
@@ -32,10 +32,6 @@ import {
32
enableTransitionTracing,
33
enableDebugTracing,
34
} from 'shared/ReactFeatureFlags';
35
-import {
36
- supportsPersistence,
37
- getOffscreenContainerType,
38
-} from './ReactFiberHostConfig';
35
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
36
import {ConcurrentRoot} from './ReactRootTags';
37
import {
@@ -605,25 +601,6 @@ export function createFiberFromTypeAndProps(
601
return fiber;
602
}
603
608
-export function createOffscreenHostContainerFiber(
609
- props: Props,
610
- fiberMode: TypeOfMode,
611
- lanes: Lanes,
612
- key: null | string,
613
-): Fiber {
614
- if (supportsPersistence) {
615
- const type = getOffscreenContainerType();
616
- const fiber = createFiber(HostComponent, props, key, fiberMode);
617
- fiber.elementType = type;
618
- fiber.type = type;
619
- fiber.lanes = lanes;
620
- return fiber;
621
- } else {
622
- // Only implemented in persistent mode
623
- throw new Error('Not implemented.');
624
- }
625
-}
626
-
604
export function createFiberFromElement(
605
element: ReactElement,
606
mode: TypeOfMode,
packages/react-reconciler/src/ReactFiberBeginWork.new.js
+2
-107
@@ -102,7 +102,6 @@ import {
102
enableLazyContextPropagation,
103
enableSuspenseLayoutEffectSemantics,
104
enableSchedulingProfiler,
105
- enablePersistentOffscreenHostContainer,
105
enableTransitionTracing,
106
enableLegacyHidden,
107
} from 'shared/ReactFeatureFlags';
@@ -161,8 +160,6 @@ import {
160
registerSuspenseInstanceRetry,
161
supportsHydration,
162
isPrimaryRenderer,
164
- supportsPersistence,
165
- getOffscreenContainerProps,
163
} from './ReactFiberHostConfig';
164
import type {SuspenseInstance} from './ReactFiberHostConfig';
165
import {shouldError, shouldSuspend} from './ReactFiberReconciler';
@@ -226,7 +223,6 @@ import {
223
createFiberFromFragment,
224
createFiberFromOffscreen,
225
createWorkInProgress,
229
- createOffscreenHostContainerFiber,
226
isSimpleFunctionComponent,
227
} from './ReactFiber.new';
228
import {
@@ -241,7 +237,6 @@ import {setWorkInProgressVersion} from './ReactMutableSource.new';
237
import {pushCacheProvider, CacheContext} from './ReactFiberCacheComponent.new';
238
import {createCapturedValue} from './ReactCapturedValue';
239
import {createClassErrorUpdate} from './ReactFiberThrow.new';
244
-import {completeSuspendedOffscreenHostContainer} from './ReactFiberCompleteWork.new';
240
import is from 'shared/objectIs';
241
import {
242
getForksAtLevel,
@@ -800,67 +795,8 @@ function updateOffscreenComponent(
795
pushRenderLanes(workInProgress, subtreeRenderLanes);
796
}
797
803
- if (enablePersistentOffscreenHostContainer && supportsPersistence) {
804
- // In persistent mode, the offscreen children are wrapped in a host node.
805
- // TODO: Optimize this to use the OffscreenComponent fiber instead of
806
- // an extra HostComponent fiber. Need to make sure this doesn't break Fabric
807
- // or some other infra that expects a HostComponent.
808
- const isHidden =
809
- nextProps.mode === 'hidden' &&
810
- (!enableLegacyHidden || workInProgress.tag !== LegacyHiddenComponent);
811
- const offscreenContainer = reconcileOffscreenHostContainer(
812
- current,
813
- workInProgress,
814
- isHidden,
815
- nextChildren,
816
- renderLanes,
817
- );
818
- return offscreenContainer;
819
- } else {
820
- reconcileChildren(current, workInProgress, nextChildren, renderLanes);
821
- return workInProgress.child;
822
- }
823
-}
824
-
825
-function reconcileOffscreenHostContainer(
826
- currentOffscreen: Fiber | null,
827
- offscreen: Fiber,
828
- isHidden: boolean,
829
- children: any,
830
- renderLanes: Lanes,
831
-) {
832
- const containerProps = getOffscreenContainerProps(
833
- isHidden ? 'hidden' : 'visible',
834
- children,
835
- );
836
- let hostContainer;
837
- if (currentOffscreen === null) {
838
- hostContainer = createOffscreenHostContainerFiber(
839
- containerProps,
840
- offscreen.mode,
841
- renderLanes,
842
- null,
843
- );
844
- } else {
845
- const currentHostContainer = currentOffscreen.child;
846
- if (currentHostContainer === null) {
847
- hostContainer = createOffscreenHostContainerFiber(
848
- containerProps,
849
- offscreen.mode,
850
- renderLanes,
851
- null,
852
- );
853
- hostContainer.flags |= Placement;
854
- } else {
855
- hostContainer = createWorkInProgress(
856
- currentHostContainer,
857
- containerProps,
858
- );
859
- }
860
- }
861
- hostContainer.return = offscreen;
862
- offscreen.child = hostContainer;
863
- return hostContainer;
798
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
799
+ return workInProgress.child;
800
}
801
802
// Note: These happen to have identical begin phases, for now. We shouldn't hold
@@ -2575,24 +2511,6 @@ function updateSuspenseFallbackChildren(
2511
currentPrimaryChildFragment.treeBaseDuration;
2512
}
2513
2578
- if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2579
- // In persistent mode, the offscreen children are wrapped in a host node.
2580
- // We need to complete it now, because we're going to skip over its normal
2581
- // complete phase and go straight to rendering the fallback.
2582
- const currentOffscreenContainer = currentPrimaryChildFragment.child;
2583
- const offscreenContainer: Fiber = (primaryChildFragment.child: any);
2584
- const containerProps = getOffscreenContainerProps(
2585
- 'hidden',
2586
- primaryChildren,
2587
- );
2588
- offscreenContainer.pendingProps = containerProps;
2589
- offscreenContainer.memoizedProps = containerProps;
2590
- completeSuspendedOffscreenHostContainer(
2591
- currentOffscreenContainer,
2592
- offscreenContainer,
2593
- );
2594
- }
2595
-
2514
// The fallback fiber was added as a deletion during the first pass.
2515
// However, since we're going to remain on the fallback, we no longer want
2516
// to delete it.
@@ -2602,29 +2520,6 @@ function updateSuspenseFallbackChildren(
2520
currentPrimaryChildFragment,
2521
primaryChildProps,
2522
);
2605
-
2606
- if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2607
- // In persistent mode, the offscreen children are wrapped in a host node.
2608
- // We need to complete it now, because we're going to skip over its normal
2609
- // complete phase and go straight to rendering the fallback.
2610
- const currentOffscreenContainer = currentPrimaryChildFragment.child;
2611
- if (currentOffscreenContainer !== null) {
2612
- const isHidden = true;
2613
- const offscreenContainer = reconcileOffscreenHostContainer(
2614
- currentPrimaryChildFragment,
2615
- primaryChildFragment,
2616
- isHidden,
2617
- primaryChildren,
2618
- renderLanes,
2619
- );
2620
- offscreenContainer.memoizedProps = offscreenContainer.pendingProps;
2621
- completeSuspendedOffscreenHostContainer(
2622
- currentOffscreenContainer,
2623
- offscreenContainer,
2624
- );
2625
- }
2626
- }
2627
-
2523
// Since we're reusing a current tree, we need to reuse the flags, too.
2524
// (We don't do this in legacy mode, because in legacy mode we don't re-use
2525
// the current tree; see previous branch.)
packages/react-reconciler/src/ReactFiberBeginWork.old.js
+2
-107
@@ -102,7 +102,6 @@ import {
102
enableLazyContextPropagation,
103
enableSuspenseLayoutEffectSemantics,
104
enableSchedulingProfiler,
105
- enablePersistentOffscreenHostContainer,
105
enableTransitionTracing,
106
enableLegacyHidden,
107
} from 'shared/ReactFeatureFlags';
@@ -161,8 +160,6 @@ import {
160
registerSuspenseInstanceRetry,
161
supportsHydration,
162
isPrimaryRenderer,
164
- supportsPersistence,
165
- getOffscreenContainerProps,
163
} from './ReactFiberHostConfig';
164
import type {SuspenseInstance} from './ReactFiberHostConfig';
165
import {shouldError, shouldSuspend} from './ReactFiberReconciler';
@@ -226,7 +223,6 @@ import {
223
createFiberFromFragment,
224
createFiberFromOffscreen,
225
createWorkInProgress,
229
- createOffscreenHostContainerFiber,
226
isSimpleFunctionComponent,
227
} from './ReactFiber.old';
228
import {
@@ -241,7 +237,6 @@ import {setWorkInProgressVersion} from './ReactMutableSource.old';
237
import {pushCacheProvider, CacheContext} from './ReactFiberCacheComponent.old';
238
import {createCapturedValue} from './ReactCapturedValue';
239
import {createClassErrorUpdate} from './ReactFiberThrow.old';
244
-import {completeSuspendedOffscreenHostContainer} from './ReactFiberCompleteWork.old';
240
import is from 'shared/objectIs';
241
import {
242
getForksAtLevel,
@@ -800,67 +795,8 @@ function updateOffscreenComponent(
795
pushRenderLanes(workInProgress, subtreeRenderLanes);
796
}
797
803
- if (enablePersistentOffscreenHostContainer && supportsPersistence) {
804
- // In persistent mode, the offscreen children are wrapped in a host node.
805
- // TODO: Optimize this to use the OffscreenComponent fiber instead of
806
- // an extra HostComponent fiber. Need to make sure this doesn't break Fabric
807
- // or some other infra that expects a HostComponent.
808
- const isHidden =
809
- nextProps.mode === 'hidden' &&
810
- (!enableLegacyHidden || workInProgress.tag !== LegacyHiddenComponent);
811
- const offscreenContainer = reconcileOffscreenHostContainer(
812
- current,
813
- workInProgress,
814
- isHidden,
815
- nextChildren,
816
- renderLanes,
817
- );
818
- return offscreenContainer;
819
- } else {
820
- reconcileChildren(current, workInProgress, nextChildren, renderLanes);
821
- return workInProgress.child;
822
- }
823
-}
824
-
825
-function reconcileOffscreenHostContainer(
826
- currentOffscreen: Fiber | null,
827
- offscreen: Fiber,
828
- isHidden: boolean,
829
- children: any,
830
- renderLanes: Lanes,
831
-) {
832
- const containerProps = getOffscreenContainerProps(
833
- isHidden ? 'hidden' : 'visible',
834
- children,
835
- );
836
- let hostContainer;
837
- if (currentOffscreen === null) {
838
- hostContainer = createOffscreenHostContainerFiber(
839
- containerProps,
840
- offscreen.mode,
841
- renderLanes,
842
- null,
843
- );
844
- } else {
845
- const currentHostContainer = currentOffscreen.child;
846
- if (currentHostContainer === null) {
847
- hostContainer = createOffscreenHostContainerFiber(
848
- containerProps,
849
- offscreen.mode,
850
- renderLanes,
851
- null,
852
- );
853
- hostContainer.flags |= Placement;
854
- } else {
855
- hostContainer = createWorkInProgress(
856
- currentHostContainer,
857
- containerProps,
858
- );
859
- }
860
- }
861
- hostContainer.return = offscreen;
862
- offscreen.child = hostContainer;
863
- return hostContainer;
798
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
799
+ return workInProgress.child;
800
}
801
802
// Note: These happen to have identical begin phases, for now. We shouldn't hold
@@ -2575,24 +2511,6 @@ function updateSuspenseFallbackChildren(
2511
currentPrimaryChildFragment.treeBaseDuration;
2512
}
2513
2578
- if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2579
- // In persistent mode, the offscreen children are wrapped in a host node.
2580
- // We need to complete it now, because we're going to skip over its normal
2581
- // complete phase and go straight to rendering the fallback.
2582
- const currentOffscreenContainer = currentPrimaryChildFragment.child;
2583
- const offscreenContainer: Fiber = (primaryChildFragment.child: any);
2584
- const containerProps = getOffscreenContainerProps(
2585
- 'hidden',
2586
- primaryChildren,
2587
- );
2588
- offscreenContainer.pendingProps = containerProps;
2589
- offscreenContainer.memoizedProps = containerProps;
2590
- completeSuspendedOffscreenHostContainer(
2591
- currentOffscreenContainer,
2592
- offscreenContainer,
2593
- );
2594
- }
2595
-
2514
// The fallback fiber was added as a deletion during the first pass.
2515
// However, since we're going to remain on the fallback, we no longer want
2516
// to delete it.
@@ -2602,29 +2520,6 @@ function updateSuspenseFallbackChildren(
2520
currentPrimaryChildFragment,
2521
primaryChildProps,
2522
);
2605
-
2606
- if (enablePersistentOffscreenHostContainer && supportsPersistence) {
2607
- // In persistent mode, the offscreen children are wrapped in a host node.
2608
- // We need to complete it now, because we're going to skip over its normal
2609
- // complete phase and go straight to rendering the fallback.
2610
- const currentOffscreenContainer = currentPrimaryChildFragment.child;
2611
- if (currentOffscreenContainer !== null) {
2612
- const isHidden = true;
2613
- const offscreenContainer = reconcileOffscreenHostContainer(
2614
- currentPrimaryChildFragment,
2615
- primaryChildFragment,
2616
- isHidden,
2617
- primaryChildren,
2618
- renderLanes,
2619
- );
2620
- offscreenContainer.memoizedProps = offscreenContainer.pendingProps;
2621
- completeSuspendedOffscreenHostContainer(
2622
- currentOffscreenContainer,
2623
- offscreenContainer,
2624
- );
2625
- }
2626
- }
2627
-
2523
// Since we're reusing a current tree, we need to reuse the flags, too.
2524
// (We don't do this in legacy mode, because in legacy mode we don't re-use
2525
// the current tree; see previous branch.)
packages/react-reconciler/src/ReactFiberCompleteWork.new.js
+2
-70
@@ -141,7 +141,6 @@ import {
141
enableProfilerTimer,
142
enableCache,
143
enableSuspenseLayoutEffectSemantics,
144
- enablePersistentOffscreenHostContainer,
144
enableTransitionTracing,
145
} from 'shared/ReactFeatureFlags';
146
import {
@@ -347,11 +346,7 @@ if (supportsMutation) {
346
if (child !== null) {
347
child.return = node;
348
}
350
- if (enablePersistentOffscreenHostContainer) {
351
- appendAllChildren(parent, node, false, false);
352
- } else {
353
- appendAllChildren(parent, node, true, true);
354
- }
349
+ appendAllChildren(parent, node, true, true);
350
} else if (node.child !== null) {
351
node.child.return = node;
352
node = node.child;
@@ -416,11 +411,7 @@ if (supportsMutation) {
411
if (child !== null) {
412
child.return = node;
413
}
419
- if (enablePersistentOffscreenHostContainer) {
420
- appendAllChildrenToContainer(containerChildSet, node, false, false);
421
- } else {
422
- appendAllChildrenToContainer(containerChildSet, node, true, true);
423
- }
414
+ appendAllChildrenToContainer(containerChildSet, node, true, true);
415
} else if (node.child !== null) {
416
node.child.return = node;
417
node = node.child;
@@ -768,65 +759,6 @@ function bubbleProperties(completedWork: Fiber) {
759
return didBailout;
760
}
761
771
-export function completeSuspendedOffscreenHostContainer(
772
- current: Fiber | null,
773
- workInProgress: Fiber,
774
-) {
775
- // This is a fork of the complete phase for HostComponent. We use it when
776
- // a suspense tree is in its fallback state, because in that case the primary
777
- // tree that includes the offscreen boundary is skipped over without a
778
- // regular complete phase.
779
- //
780
- // We can optimize this path further by inlining the update logic for
781
- // offscreen instances specifically, i.e. skipping the `prepareUpdate` call.
782
- const rootContainerInstance = getRootHostContainer();
783
- const type = workInProgress.type;
784
- const newProps = workInProgress.memoizedProps;
785
- if (current !== null) {
786
- updateHostComponent(
787
- current,
788
- workInProgress,
789
- type,
790
- newProps,
791
- rootContainerInstance,
792
- );
793
- } else {
794
- const currentHostContext = getHostContext();
795
- const instance = createInstance(
796
- type,
797
- newProps,
798
- rootContainerInstance,
799
- currentHostContext,
800
- workInProgress,
801
- );
802
-
803
- appendAllChildren(instance, workInProgress, false, false);
804
-
805
- workInProgress.stateNode = instance;
806
-
807
- // Certain renderers require commit-time effects for initial mount.
808
- // (eg DOM renderer supports auto-focus for certain elements).
809
- // Make sure such renderers get scheduled for later work.
810
- if (
811
- finalizeInitialChildren(
812
- instance,
813
- type,
814
- newProps,
815
- rootContainerInstance,
816
- currentHostContext,
817
- )
818
- ) {
819
- markUpdate(workInProgress);
820
- }
821
-
822
- if (workInProgress.ref !== null) {
823
- // If there is a ref on a host node we need to schedule a callback
824
- markRef(workInProgress);
825
- }
826
- }
827
- bubbleProperties(workInProgress);
828
-}
829
-
762
function completeWork(
763
current: Fiber | null,
764
workInProgress: Fiber,
packages/react-reconciler/src/ReactFiberCompleteWork.old.js
+2
-70
@@ -141,7 +141,6 @@ import {
141
enableProfilerTimer,
142
enableCache,
143
enableSuspenseLayoutEffectSemantics,
144
- enablePersistentOffscreenHostContainer,
144
enableTransitionTracing,
145
} from 'shared/ReactFeatureFlags';
146
import {
@@ -347,11 +346,7 @@ if (supportsMutation) {
346
if (child !== null) {
347
child.return = node;
348
}
350
- if (enablePersistentOffscreenHostContainer) {
351
- appendAllChildren(parent, node, false, false);
352
- } else {
353
- appendAllChildren(parent, node, true, true);
354
- }
349
+ appendAllChildren(parent, node, true, true);
350
} else if (node.child !== null) {
351
node.child.return = node;
352
node = node.child;
@@ -416,11 +411,7 @@ if (supportsMutation) {
411
if (child !== null) {
412
child.return = node;
413
}
419
- if (enablePersistentOffscreenHostContainer) {
420
- appendAllChildrenToContainer(containerChildSet, node, false, false);
421
- } else {
422
- appendAllChildrenToContainer(containerChildSet, node, true, true);
423
- }
414
+ appendAllChildrenToContainer(containerChildSet, node, true, true);
415
} else if (node.child !== null) {
416
node.child.return = node;
417
node = node.child;
@@ -768,65 +759,6 @@ function bubbleProperties(completedWork: Fiber) {
759
return didBailout;
760
}
761
771
-export function completeSuspendedOffscreenHostContainer(
772
- current: Fiber | null,
773
- workInProgress: Fiber,
774
-) {
775
- // This is a fork of the complete phase for HostComponent. We use it when
776
- // a suspense tree is in its fallback state, because in that case the primary
777
- // tree that includes the offscreen boundary is skipped over without a
778
- // regular complete phase.
779
- //
780
- // We can optimize this path further by inlining the update logic for
781
- // offscreen instances specifically, i.e. skipping the `prepareUpdate` call.
782
- const rootContainerInstance = getRootHostContainer();
783
- const type = workInProgress.type;
784
- const newProps = workInProgress.memoizedProps;
785
- if (current !== null) {
786
- updateHostComponent(
787
- current,
788
- workInProgress,
789
- type,
790
- newProps,
791
- rootContainerInstance,
792
- );
793
- } else {
794
- const currentHostContext = getHostContext();
795
- const instance = createInstance(
796
- type,
797
- newProps,
798
- rootContainerInstance,
799
- currentHostContext,
800
- workInProgress,
801
- );
802
-
803
- appendAllChildren(instance, workInProgress, false, false);
804
-
805
- workInProgress.stateNode = instance;
806
-
807
- // Certain renderers require commit-time effects for initial mount.
808
- // (eg DOM renderer supports auto-focus for certain elements).
809
- // Make sure such renderers get scheduled for later work.
810
- if (
811
- finalizeInitialChildren(
812
- instance,
813
- type,
814
- newProps,
815
- rootContainerInstance,
816
- currentHostContext,
817
- )
818
- ) {
819
- markUpdate(workInProgress);
820
- }
821
-
822
- if (workInProgress.ref !== null) {
823
- // If there is a ref on a host node we need to schedule a callback
824
- markRef(workInProgress);
825
- }
826
- }
827
- bubbleProperties(workInProgress);
828
-}
829
-
762
function completeWork(
763
current: Fiber | null,
764
workInProgress: Fiber,
packages/react-reconciler/src/ReactFiberHostConfigWithNoPersistence.js
-2
@@ -25,7 +25,5 @@ export const createContainerChildSet = shim;
25
export const appendChildToContainerChildSet = shim;
26
export const finalizeContainerChildren = shim;
27
export const replaceContainerChildren = shim;
28
-export const getOffscreenContainerType = shim;
29
-export const getOffscreenContainerProps = shim;
28
export const cloneHiddenInstance = shim;
29
export const cloneHiddenTextInstance = shim;
packages/react-reconciler/src/ReactFiberThrow.new.js
-25
@@ -34,17 +34,12 @@ import {
34
ForceUpdateForLegacySuspense,
35
ForceClientRender,
36
} from './ReactFiberFlags';
37
-import {
38
- supportsPersistence,
39
- getOffscreenContainerProps,
40
-} from './ReactFiberHostConfig';
37
import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.new';
38
import {NoMode, ConcurrentMode, DebugTracingMode} from './ReactTypeOfMode';
39
import {
40
enableDebugTracing,
41
enableLazyContextPropagation,
42
enableUpdaterTracking,
47
- enablePersistentOffscreenHostContainer,
43
} from 'shared/ReactFeatureFlags';
44
import {createCapturedValue} from './ReactCapturedValue';
45
import {
@@ -336,26 +331,6 @@ function markSuspenseBoundaryShouldCapture(
331
// all lifecycle effect tags.
332
sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
333
339
- if (supportsPersistence && enablePersistentOffscreenHostContainer) {
340
- // Another legacy Suspense quirk. In persistent mode, if this is the
341
- // initial mount, override the props of the host container to hide
342
- // its contents.
343
- const currentSuspenseBoundary = suspenseBoundary.alternate;
344
- if (currentSuspenseBoundary === null) {
345
- const offscreenFiber: Fiber = (suspenseBoundary.child: any);
346
- const offscreenContainer = offscreenFiber.child;
347
- if (offscreenContainer !== null) {
348
- const children = offscreenContainer.memoizedProps.children;
349
- const containerProps = getOffscreenContainerProps(
350
- 'hidden',
351
- children,
352
- );
353
- offscreenContainer.pendingProps = containerProps;
354
- offscreenContainer.memoizedProps = containerProps;
355
- }
356
- }
357
- }
358
-
334
if (sourceFiber.tag === ClassComponent) {
335
const currentSourceFiber = sourceFiber.alternate;
336
if (currentSourceFiber === null) {
packages/react-reconciler/src/ReactFiberThrow.old.js
-25
@@ -34,17 +34,12 @@ import {
34
ForceUpdateForLegacySuspense,
35
ForceClientRender,
36
} from './ReactFiberFlags';
37
-import {
38
- supportsPersistence,
39
- getOffscreenContainerProps,
40
-} from './ReactFiberHostConfig';
37
import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.old';
38
import {NoMode, ConcurrentMode, DebugTracingMode} from './ReactTypeOfMode';
39
import {
40
enableDebugTracing,
41
enableLazyContextPropagation,
42
enableUpdaterTracking,
47
- enablePersistentOffscreenHostContainer,
43
} from 'shared/ReactFeatureFlags';
44
import {createCapturedValue} from './ReactCapturedValue';
45
import {
@@ -336,26 +331,6 @@ function markSuspenseBoundaryShouldCapture(
331
// all lifecycle effect tags.
332
sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
333
339
- if (supportsPersistence && enablePersistentOffscreenHostContainer) {
340
- // Another legacy Suspense quirk. In persistent mode, if this is the
341
- // initial mount, override the props of the host container to hide
342
- // its contents.
343
- const currentSuspenseBoundary = suspenseBoundary.alternate;
344
- if (currentSuspenseBoundary === null) {
345
- const offscreenFiber: Fiber = (suspenseBoundary.child: any);
346
- const offscreenContainer = offscreenFiber.child;
347
- if (offscreenContainer !== null) {
348
- const children = offscreenContainer.memoizedProps.children;
349
- const containerProps = getOffscreenContainerProps(
350
- 'hidden',
351
- children,
352
- );
353
- offscreenContainer.pendingProps = containerProps;
354
- offscreenContainer.memoizedProps = containerProps;
355
- }
356
- }
357
- }
358
-
334
if (sourceFiber.tag === ClassComponent) {
335
const currentSourceFiber = sourceFiber.alternate;
336
if (currentSourceFiber === null) {
packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js
-4
@@ -121,10 +121,6 @@ export const appendChildToContainerChildSet =
121
export const finalizeContainerChildren =
122
$$$hostConfig.finalizeContainerChildren;
123
export const replaceContainerChildren = $$$hostConfig.replaceContainerChildren;
124
-export const getOffscreenContainerType =
125
- $$$hostConfig.getOffscreenContainerType;
126
-export const getOffscreenContainerProps =
127
- $$$hostConfig.getOffscreenContainerProps;
124
export const cloneHiddenInstance = $$$hostConfig.cloneHiddenInstance;
125
export const cloneHiddenTextInstance = $$$hostConfig.cloneHiddenTextInstance;
126
packages/shared/ReactFeatureFlags.js
-1
@@ -16,7 +16,6 @@
16
export const warnAboutDeprecatedLifecycles = true;
17
export const enableComponentStackLocations = true;
18
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
19
-export const enablePersistentOffscreenHostContainer = false;
19
20
// -----------------------------------------------------------------------------
21
// Land or remove (moderate effort)
packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
+9
-9
@@ -7,8 +7,10 @@
7
* @flow strict
8
*/
9
10
-import typeof * as ExportsType from './ReactFeatureFlags.native-fb-dynamic';
11
-import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags';
10
+// NOTE: There are no flags, currently. Uncomment the stuff below if we add one.
11
+
12
+// import typeof * as ExportsType from './ReactFeatureFlags.native-fb-dynamic';
13
+// import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags';
14
15
// In xplat, these flags are controlled by GKs. Because most GKs have some
16
// population running in either mode, we should run our tests that way, too,
@@ -20,10 +22,8 @@ import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags';
22
// flag here but it won't be set to `true` in any of our test runs. Need to
23
// update the test configuration.
24
23
-export const enablePersistentOffscreenHostContainer = __VARIANT__;
24
-
25
-// Flow magic to verify the exports of this file match the original version.
26
-// eslint-disable-next-line no-unused-vars
27
-type Check<_X, Y: _X, X: Y = _X> = null;
28
-// eslint-disable-next-line no-unused-expressions
29
-(null: Check<ExportsType, DynamicFlagsType>);
25
+// // Flow magic to verify the exports of this file match the original version.
26
+// // eslint-disable-next-line no-unused-vars
27
+// type Check<_X, Y: _X, X: Y = _X> = null;
28
+// // eslint-disable-next-line no-unused-expressions
29
+// (null: Check<ExportsType, DynamicFlagsType>);
packages/shared/forks/ReactFeatureFlags.native-fb.js
+3
-2
@@ -10,13 +10,14 @@
10
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
11
import typeof * as ExportsType from './ReactFeatureFlags.native-fb';
12
13
+// NOTE: There are no flags, currently. Uncomment the stuff below if we add one.
14
// Re-export dynamic flags from the internal module. Intentionally using *
15
// because this import is compiled to a `require` call.
15
-import * as dynamicFlags from 'ReactNativeInternalFeatureFlags';
16
+// import * as dynamicFlags from 'ReactNativeInternalFeatureFlags';
17
18
// We destructure each value before re-exporting to avoid a dynamic look-up on
19
// the exports object every time a flag is read.
19
-export const {enablePersistentOffscreenHostContainer} = dynamicFlags;
20
+// export const {} = dynamicFlags;
21
22
// The rest of the flags are static for better dead code elimination.
23
export const enableDebugTracing = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62
export const enableLegacyHidden = false;
63
export const enableSyncDefaultUpdates = true;
64
export const allowConcurrentByDefault = false;
65
-export const enablePersistentOffscreenHostContainer = false;
65
export const enableCustomElementPropertySupport = false;
66
67
export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62
export const enableLegacyHidden = false;
63
export const enableSyncDefaultUpdates = true;
64
export const allowConcurrentByDefault = false;
65
-export const enablePersistentOffscreenHostContainer = false;
65
export const enableCustomElementPropertySupport = false;
66
67
export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
-1
@@ -61,7 +61,6 @@ export const enableLazyContextPropagation = false;
61
export const enableLegacyHidden = false;
62
export const enableSyncDefaultUpdates = true;
63
export const allowConcurrentByDefault = true;
64
-export const enablePersistentOffscreenHostContainer = false;
64
65
export const consoleManagedByDevToolsDuringStrictMode = false;
66
export const enableServerContext = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62
export const enableLegacyHidden = false;
63
export const enableSyncDefaultUpdates = true;
64
export const allowConcurrentByDefault = true;
65
-export const enablePersistentOffscreenHostContainer = false;
65
export const enableCustomElementPropertySupport = false;
66
67
export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.testing.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62
export const enableLegacyHidden = false;
63
export const enableSyncDefaultUpdates = true;
64
export const allowConcurrentByDefault = false;
65
-export const enablePersistentOffscreenHostContainer = false;
65
export const enableCustomElementPropertySupport = false;
66
67
export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.testing.www.js
-1
@@ -62,7 +62,6 @@ export const enableLazyContextPropagation = false;
62
export const enableLegacyHidden = false;
63
export const enableSyncDefaultUpdates = true;
64
export const allowConcurrentByDefault = true;
65
-export const enablePersistentOffscreenHostContainer = false;
65
export const enableCustomElementPropertySupport = false;
66
67
export const consoleManagedByDevToolsDuringStrictMode = false;
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
-1
@@ -60,6 +60,5 @@ export const disableNativeComponentFrames = false;
60
export const createRootStrictEffectsByDefault = false;
61
export const enableStrictEffects = false;
62
export const allowConcurrentByDefault = true;
63
-export const enablePersistentOffscreenHostContainer = false;
63
// You probably *don't* want to add more hardcoded ones.
64
// Instead, try to add them above with the __VARIANT__ value.
packages/shared/forks/ReactFeatureFlags.www.js
-2
@@ -99,8 +99,6 @@ export const allowConcurrentByDefault = true;
99
100
export const deletedTreeCleanUpLevel = 3;
101
102
-export const enablePersistentOffscreenHostContainer = false;
103
-
102
export const consoleManagedByDevToolsDuringStrictMode = true;
103
export const enableServerContext = true;
104
scripts/flow/xplat.js
-1
@@ -8,5 +8,4 @@
8
*/
9
10
declare module 'ReactNativeInternalFeatureFlags' {
11
- declare export var enablePersistentOffscreenHostContainer: boolean;
11
}