Refactor commitPlacement to recursively insert nodes (#17996)
Dominic Gannaway committed
Feb 10, 2020 at 23:38 UTC
df5faddcc2ad27be5700823d4f5367e5e9ae4620
2 files changed
+62
-34
packages/react-dom/src/client/ReactDOMHostConfig.js
+1
-1
@@ -88,7 +88,7 @@ export type EventTargetChildElement = {
88
},
89
...
90
};
91
-export type Container = Element | Document;
91
+export type Container = DOMContainer;
92
export type Instance = Element;
93
export type TextInstance = Text;
94
export type SuspenseInstance = Comment & {_reactRetry?: () => void, ...};
packages/react-reconciler/src/ReactFiberCommitWork.js
+61
-33
@@ -1099,44 +1099,72 @@ function commitPlacement(finishedWork: Fiber): void {
1099
const before = getHostSibling(finishedWork);
1100
// We only have the top Fiber that was inserted but we need to recurse down its
1101
// children to find all the terminal nodes.
1102
- let node: Fiber = finishedWork;
1103
- while (true) {
1104
- const isHost = node.tag === HostComponent || node.tag === HostText;
1105
- if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) {
1106
- const stateNode = isHost ? node.stateNode : node.stateNode.instance;
1107
- if (before) {
1108
- if (isContainer) {
1109
- insertInContainerBefore(parent, stateNode, before);
1110
- } else {
1111
- insertBefore(parent, stateNode, before);
1112
- }
1113
- } else {
1114
- if (isContainer) {
1115
- appendChildToContainer(parent, stateNode);
1116
- } else {
1117
- appendChild(parent, stateNode);
1118
- }
1102
+ if (isContainer) {
1103
+ insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
1104
+ } else {
1105
+ insertOrAppendPlacementNode(finishedWork, before, parent);
1106
+ }
1107
+}
1108
+
1109
+function insertOrAppendPlacementNodeIntoContainer(
1110
+ node: Fiber,
1111
+ before: ?Instance,
1112
+ parent: Container,
1113
+): void {
1114
+ const {tag} = node;
1115
+ const isHost = tag === HostComponent || tag === HostText;
1116
+ if (isHost || (enableFundamentalAPI && tag === FundamentalComponent)) {
1117
+ const stateNode = isHost ? node.stateNode : node.stateNode.instance;
1118
+ if (before) {
1119
+ insertInContainerBefore(parent, stateNode, before);
1120
+ } else {
1121
+ appendChildToContainer(parent, stateNode);
1122
+ }
1123
+ } else if (tag === HostPortal) {
1124
+ // If the insertion itself is a portal, then we don't want to traverse
1125
+ // down its children. Instead, we'll get insertions from each child in
1126
+ // the portal directly.
1127
+ } else {
1128
+ const child = node.child;
1129
+ if (child !== null) {
1130
+ insertOrAppendPlacementNodeIntoContainer(child, before, parent);
1131
+ let sibling = child.sibling;
1132
+ while (sibling !== null) {
1133
+ insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
1134
+ sibling = sibling.sibling;
1135
}
1120
- } else if (node.tag === HostPortal) {
1121
- // If the insertion itself is a portal, then we don't want to traverse
1122
- // down its children. Instead, we'll get insertions from each child in
1123
- // the portal directly.
1124
- } else if (node.child !== null) {
1125
- node.child.return = node;
1126
- node = node.child;
1127
- continue;
1136
}
1129
- if (node === finishedWork) {
1130
- return;
1137
+ }
1138
+}
1139
+
1140
+function insertOrAppendPlacementNode(
1141
+ node: Fiber,
1142
+ before: ?Instance,
1143
+ parent: Instance,
1144
+): void {
1145
+ const {tag} = node;
1146
+ const isHost = tag === HostComponent || tag === HostText;
1147
+ if (isHost || (enableFundamentalAPI && tag === FundamentalComponent)) {
1148
+ const stateNode = isHost ? node.stateNode : node.stateNode.instance;
1149
+ if (before) {
1150
+ insertBefore(parent, stateNode, before);
1151
+ } else {
1152
+ appendChild(parent, stateNode);
1153
}
1132
- while (node.sibling === null) {
1133
- if (node.return === null || node.return === finishedWork) {
1134
- return;
1154
+ } else if (tag === HostPortal) {
1155
+ // If the insertion itself is a portal, then we don't want to traverse
1156
+ // down its children. Instead, we'll get insertions from each child in
1157
+ // the portal directly.
1158
+ } else {
1159
+ const child = node.child;
1160
+ if (child !== null) {
1161
+ insertOrAppendPlacementNode(child, before, parent);
1162
+ let sibling = child.sibling;
1163
+ while (sibling !== null) {
1164
+ insertOrAppendPlacementNode(sibling, before, parent);
1165
+ sibling = sibling.sibling;
1166
}
1136
- node = node.return;
1167
}
1138
- node.sibling.return = node.return;
1139
- node = node.sibling;
1168
}
1169
}
1170