From 024e2a02591578dcf91ac68920b1ea0ff82f3949 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 24 Nov 2016 00:17:59 +0000 Subject: [PATCH] Remove recursion from unmounting portals (#1) --- .../shared/fiber/ReactFiberCommitWork.js | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberCommitWork.js b/src/renderers/shared/fiber/ReactFiberCommitWork.js index 0fe3c232bd..2636429ac2 100644 --- a/src/renderers/shared/fiber/ReactFiberCommitWork.js +++ b/src/renderers/shared/fiber/ReactFiberCommitWork.js @@ -207,17 +207,11 @@ module.exports = function( // node from the tree. removeChild(parent, node.stateNode); } else if (node.tag === Portal) { - // If this is a portal, then the parent is actually the portal itself. - // We need to keep track of which parent we're removing from. - // TODO: This uses a recursive call. We can get rid of that by mutating - // the parent binding and restoring it by searching for the host parent - // again when we pop past a portal. - const portalParent = node.stateNode.containerInfo; - let child = node.child; - while (child) { - unmountHostComponents(portalParent, child); - child = child.sibling; - } + // When we go into a portal, it becomes the parent to remove from. + // We will reassign it back when we pop the portal on the way up. + parent = node.stateNode.containerInfo; + node = node.child; + continue; } else { commitUnmount(node); if (node.child) { @@ -235,6 +229,11 @@ module.exports = function( return; } node = node.return; + if (node.tag === Portal) { + // When we go out of the portal, we need to restore the parent. + // Since we don't keep a stack of them, we will search for it. + parent = getHostParent(node); + } } node.sibling.return = node.return; node = node.sibling;