Skip to content

Commit ce13860

Browse files
authored
Remove enablePersistentOffscreenHostContainer flag (#24460)
This was a Fabric-related experiment that we ended up not shipping.
1 parent 340060c commit ce13860

24 files changed

+25
-688
lines changed

packages/react-native-renderer/src/ReactFabricHostConfig.js

-32
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
* @flow
88
*/
99

10-
import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
1110
import type {ElementRef} from 'react';
1211
import type {
1312
HostComponent,
@@ -545,37 +544,6 @@ export function cloneInstance(
545544
};
546545
}
547546

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-
579547
export function cloneHiddenInstance(
580548
instance: Instance,
581549
type: string,

packages/react-noop-renderer/src/createReactNoop.js

+3-176
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type {
1919
TransitionTracingCallbacks,
2020
} from 'react-reconciler/src/ReactInternalTypes';
2121
import type {UpdateQueue} from 'react-reconciler/src/ReactUpdateQueue';
22-
import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
22+
import type {ReactNodeList} from 'shared/ReactTypes';
2323
import type {RootTag} from 'react-reconciler/src/ReactRootTags';
2424

2525
import * as Scheduler from 'scheduler/unstable_mock';
@@ -595,20 +595,6 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
595595
container.children = newChildren;
596596
},
597597

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-
612598
cloneHiddenInstance(
613599
instance: Instance,
614600
type: string,
@@ -721,179 +707,20 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
721707

722708
function getChildren(root) {
723709
if (root) {
724-
return useMutation
725-
? root.children
726-
: removeOffscreenContainersFromChildren(root.children, false);
710+
return root.children;
727711
} else {
728712
return null;
729713
}
730714
}
731715

732716
function getPendingChildren(root) {
733717
if (root) {
734-
return useMutation
735-
? root.children
736-
: removeOffscreenContainersFromChildren(root.pendingChildren, false);
718+
return root.children;
737719
} else {
738720
return null;
739721
}
740722
}
741723

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-
897724
function getChildrenAsJSX(root) {
898725
const children = childToJSX(getChildren(root), null);
899726
if (children === null) {

packages/react-reconciler/src/ReactFiber.new.js

+1-24
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {RootTag} from './ReactRootTags';
1414
import type {WorkTag} from './ReactWorkTags';
1515
import type {TypeOfMode} from './ReactTypeOfMode';
1616
import type {Lanes} from './ReactFiberLane.new';
17-
import type {SuspenseInstance, Props} from './ReactFiberHostConfig';
17+
import type {SuspenseInstance} from './ReactFiberHostConfig';
1818
import type {
1919
OffscreenProps,
2020
OffscreenInstance,
@@ -32,10 +32,6 @@ import {
3232
enableTransitionTracing,
3333
enableDebugTracing,
3434
} from 'shared/ReactFeatureFlags';
35-
import {
36-
supportsPersistence,
37-
getOffscreenContainerType,
38-
} from './ReactFiberHostConfig';
3935
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
4036
import {ConcurrentRoot} from './ReactRootTags';
4137
import {
@@ -605,25 +601,6 @@ export function createFiberFromTypeAndProps(
605601
return fiber;
606602
}
607603

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-
627604
export function createFiberFromElement(
628605
element: ReactElement,
629606
mode: TypeOfMode,

packages/react-reconciler/src/ReactFiber.old.js

+1-24
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {RootTag} from './ReactRootTags';
1414
import type {WorkTag} from './ReactWorkTags';
1515
import type {TypeOfMode} from './ReactTypeOfMode';
1616
import type {Lanes} from './ReactFiberLane.old';
17-
import type {SuspenseInstance, Props} from './ReactFiberHostConfig';
17+
import type {SuspenseInstance} from './ReactFiberHostConfig';
1818
import type {
1919
OffscreenProps,
2020
OffscreenInstance,
@@ -32,10 +32,6 @@ import {
3232
enableTransitionTracing,
3333
enableDebugTracing,
3434
} from 'shared/ReactFeatureFlags';
35-
import {
36-
supportsPersistence,
37-
getOffscreenContainerType,
38-
} from './ReactFiberHostConfig';
3935
import {NoFlags, Placement, StaticMask} from './ReactFiberFlags';
4036
import {ConcurrentRoot} from './ReactRootTags';
4137
import {
@@ -605,25 +601,6 @@ export function createFiberFromTypeAndProps(
605601
return fiber;
606602
}
607603

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-
627604
export function createFiberFromElement(
628605
element: ReactElement,
629606
mode: TypeOfMode,

0 commit comments

Comments
 (0)