@samitouri / QOS-React-2 / commits / df5faddcc2

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