,
+ container
+ );
+ expect(portalContainer.innerHTML).toBe('');
+ expect(container.innerHTML).toBe('');
+ });
+
it('should keep track of namespace across portals (simple)', () => {
assertNamespacesMatch(
);
});
diff --git a/src/renderers/shared/fiber/ReactChildFiber.js b/src/renderers/shared/fiber/ReactChildFiber.js
index 413fd234f6ab7..e7ee06f88c41f 100644
--- a/src/renderers/shared/fiber/ReactChildFiber.js
+++ b/src/renderers/shared/fiber/ReactChildFiber.js
@@ -341,7 +341,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
} else {
// Update
const existing = useFiber(current, priority);
- existing.pendingProps = portal.children;
+ existing.pendingProps = portal.children || [];
existing.return = returnFiber;
return existing;
}
@@ -976,7 +976,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
) {
deleteRemainingChildren(returnFiber, child.sibling);
const existing = useFiber(child, priority);
- existing.pendingProps = portal.children;
+ existing.pendingProps = portal.children || [];
existing.return = returnFiber;
return existing;
} else {
diff --git a/src/renderers/shared/fiber/ReactFiber.js b/src/renderers/shared/fiber/ReactFiber.js
index 98e47ecaab3f1..7d3097ffaf4f7 100644
--- a/src/renderers/shared/fiber/ReactFiber.js
+++ b/src/renderers/shared/fiber/ReactFiber.js
@@ -346,7 +346,7 @@ exports.createFiberFromYield = function(yieldNode : ReactYield, priorityLevel :
exports.createFiberFromPortal = function(portal : ReactPortal, priorityLevel : PriorityLevel) : Fiber {
const fiber = createFiber(HostPortal, portal.key);
- fiber.pendingProps = portal.children;
+ fiber.pendingProps = portal.children || [];
fiber.pendingWorkPriority = priorityLevel;
fiber.stateNode = {
containerInfo: portal.containerInfo,
diff --git a/src/renderers/shared/fiber/ReactFiberCommitWork.js b/src/renderers/shared/fiber/ReactFiberCommitWork.js
index 5e31b11fcc12b..46f0fdc94b560 100644
--- a/src/renderers/shared/fiber/ReactFiberCommitWork.js
+++ b/src/renderers/shared/fiber/ReactFiberCommitWork.js
@@ -152,7 +152,9 @@ module.exports = function(
// If we don't have a child, try the siblings instead.
continue siblings;
}
- if (!node.child) {
+ // If we don't have a child, try the siblings instead.
+ // We also skip portals because they are not part of this host tree.
+ if (!node.child || node.tag === HostPortal) {
continue siblings;
} else {
node.child.return = node;
@@ -235,7 +237,9 @@ module.exports = function(
let node : Fiber = root;
while (true) {
commitUnmount(node);
- if (node.child) {
+ // Visit children because they may contain more composite or host nodes.
+ // Skip portals because commitUnmount() currently visits them recursively.
+ if (node.child && node.tag !== HostPortal) {
// TODO: Coroutines need to visit the stateNode.
node.child.return = node;
node = node.child;
@@ -265,16 +269,20 @@ module.exports = function(
// After all the children have unmounted, it is now safe to remove the
// node from the tree.
removeChild(parent, node.stateNode);
+ // Don't visit children because we already visited them.
} else if (node.tag === HostPortal) {
// 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;
+ // Visit children because portals might contain host components.
if (node.child) {
+ node.child.return = node;
node = node.child;
continue;
}
} else {
commitUnmount(node);
+ // Visit children because we may find more host components below.
if (node.child) {
// TODO: Coroutines need to visit the stateNode.
node.child.return = node;
@@ -343,7 +351,10 @@ module.exports = function(
}
case HostPortal: {
// TODO: this is recursive.
- commitDeletion(current);
+ // We are also not using this parent because
+ // the portal will get pushed immediately.
+ const parent = getHostParent(current);
+ unmountHostComponents(parent, current);
return;
}
}