Remove recursion from unmounting portals (#1)
Dan Abramov committed
Nov 24, 2016 at 00:17 UTC
024e2a02591578dcf91ac68920b1ea0ff82f3949
1 file changed
+10
-11
src/renderers/shared/fiber/ReactFiberCommitWork.js
+10
-11
@@ -207,17 +207,11 @@ module.exports = function<T, P, I, TI, C>(
207
// node from the tree.
208
removeChild(parent, node.stateNode);
209
} else if (node.tag === Portal) {
210
- // If this is a portal, then the parent is actually the portal itself.
211
- // We need to keep track of which parent we're removing from.
212
- // TODO: This uses a recursive call. We can get rid of that by mutating
213
- // the parent binding and restoring it by searching for the host parent
214
- // again when we pop past a portal.
215
- const portalParent = node.stateNode.containerInfo;
216
- let child = node.child;
217
- while (child) {
218
- unmountHostComponents(portalParent, child);
219
- child = child.sibling;
220
- }
210
+ // When we go into a portal, it becomes the parent to remove from.
211
+ // We will reassign it back when we pop the portal on the way up.
212
+ parent = node.stateNode.containerInfo;
213
+ node = node.child;
214
+ continue;
215
} else {
216
commitUnmount(node);
217
if (node.child) {
@@ -235,6 +229,11 @@ module.exports = function<T, P, I, TI, C>(
229
return;
230
}
231
node = node.return;
232
+ if (node.tag === Portal) {
233
+ // When we go out of the portal, we need to restore the parent.
234
+ // Since we don't keep a stack of them, we will search for it.
235
+ parent = getHostParent(node);
236
+ }
237
}
238
node.sibling.return = node.return;
239
node = node.sibling;