Skip to content

Commit

Permalink
[Fabric] Track child set as array instead of native datastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
javache committed Oct 5, 2023
1 parent 096cef5 commit 60b0d0f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 14 deletions.
25 changes: 19 additions & 6 deletions packages/react-native-renderer/src/ReactFiberConfigFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ const {
unstable_getCurrentEventPriority: fabricGetCurrentEventPriority,
} = nativeFabricUIManager;

import {useMicrotasksForSchedulingInFabric} from 'shared/ReactFeatureFlags';
import {
useMicrotasksForSchedulingInFabric,
passChildrenWhenCloningPersistedNodes,
} from 'shared/ReactFeatureFlags';

const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;

Expand Down Expand Up @@ -87,7 +90,7 @@ export type TextInstance = {
export type HydratableInstance = Instance | TextInstance;
export type PublicInstance = ReactNativePublicInstance;
export type Container = number;
export type ChildSet = Object;
export type ChildSet = Object | Array<Node>;
export type HostContext = $ReadOnly<{
isInAParentText: boolean,
}>;
Expand Down Expand Up @@ -405,15 +408,23 @@ export function cloneHiddenTextInstance(
throw new Error('Not yet implemented.');
}

export function createContainerChildSet(container: Container): ChildSet {
return createChildNodeSet(container);
export function createContainerChildSet(): ChildSet {
if (passChildrenWhenCloningPersistedNodes) {
return [];
} else {
return createChildNodeSet();
}
}

export function appendChildToContainerChildSet(
childSet: ChildSet,
child: Instance | TextInstance,
): void {
appendChildNodeToSet(childSet, child.node);
if (passChildrenWhenCloningPersistedNodes) {
childSet.push(child.node);
} else {
appendChildNodeToSet(childSet, child.node);
}
}

export function finalizeContainerChildren(
Expand All @@ -426,7 +437,9 @@ export function finalizeContainerChildren(
export function replaceContainerChildren(
container: Container,
newChildren: ChildSet,
): void {}
): void {
// Noop - children will be replaced in finalizeContainerChildren
}

export function getInstanceFromNode(node: any): empty {
throw new Error('Not yet implemented.');
Expand Down
4 changes: 1 addition & 3 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
cloneInstance,
clearContainer,

createContainerChildSet(
container: Container,
): Array<Instance | TextInstance> {
createContainerChildSet(): Array<Instance | TextInstance> {
return [];
},

Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactFiberCommitWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -1724,7 +1724,7 @@ function emptyPortalContainer(current: Fiber) {
...
} = current.stateNode;
const {containerInfo} = portal;
const emptyChildSet = createContainerChildSet(containerInfo);
const emptyChildSet = createContainerChildSet();
replaceContainerChildren(containerInfo, emptyChildSet);
}

Expand Down
21 changes: 18 additions & 3 deletions packages/react-reconciler/src/ReactFiberCompleteWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ function appendAllChildrenToContainer(
}
}
}

function updateHostContainer(current: null | Fiber, workInProgress: Fiber) {
if (supportsPersistence) {
const portalOrRoot: {
Expand All @@ -402,16 +403,22 @@ function updateHostContainer(current: null | Fiber, workInProgress: Fiber) {
// No changes, just reuse the existing instance.
} else {
const container = portalOrRoot.containerInfo;
const newChildSet = createContainerChildSet(container);
const newChildSet = createContainerChildSet();
// If children might have changed, we have to add them all to the set.
appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
appendAllChildrenToContainer(
newChildSet,
workInProgress,
/* needsVisibilityToggle */ false,
/* isHidden */ false,
);
portalOrRoot.pendingChildren = newChildSet;
// Schedule an update on the container to swap out the container.
markUpdate(workInProgress);
finalizeContainerChildren(container, newChildSet);
}
}
}

function updateHostComponent(
current: Fiber,
workInProgress: Fiber,
Expand Down Expand Up @@ -460,6 +467,9 @@ function updateHostComponent(
return;
}

// Certain renderers require commit-time effects for initial mount.
// (eg DOM renderer supports auto-focus for certain elements).
// Make sure such renderers get scheduled for later work.
if (
finalizeInitialChildren(newInstance, type, newProps, currentHostContext)
) {
Expand All @@ -473,7 +483,12 @@ function updateHostComponent(
markUpdate(workInProgress);
} else {
// If children might have changed, we have to add them all to the set.
appendAllChildren(newInstance, workInProgress, false, false);
appendAllChildren(
newInstance,
workInProgress,
/* needsVisibilityToggle */ false,
/* isHidden */ false,
);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/flow/react-native-host-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ declare var nativeFabricUIManager: {
cloneNodeWithNewChildrenAndProps: (node: Object, newProps: ?Object) => Object,
appendChild: (node: Object, childNode: Object) => void,

createChildSet: (rootTag: number) => Object,
createChildSet: () => Object,
appendChildToSet: (childSet: Object, childNode: Object) => void,
completeRoot: (rootTag: number, childSet: Object) => void,
registerEventHandler: (
Expand Down

0 comments on commit 60b0d0f

Please sign in to comment.