diff --git a/src/renderers/dom/fiber/ReactDOMFiberEntry.js b/src/renderers/dom/fiber/ReactDOMFiberEntry.js index 13c59b88a4d3f..8ce0ca92ff12e 100644 --- a/src/renderers/dom/fiber/ReactDOMFiberEntry.js +++ b/src/renderers/dom/fiber/ReactDOMFiberEntry.js @@ -536,7 +536,7 @@ function renderSubtreeIntoContainer( if (__DEV__) { if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { - const hostInstance = DOMRenderer.findHostInstance( + const hostInstance = DOMRenderer.findHostInstanceWithNoPortals( container._reactRootContainer.current, ); if (hostInstance) { diff --git a/src/renderers/shared/fiber/ReactFiberReconciler.js b/src/renderers/shared/fiber/ReactFiberReconciler.js index d2f38655226dd..07c642cb2b7fd 100644 --- a/src/renderers/shared/fiber/ReactFiberReconciler.js +++ b/src/renderers/shared/fiber/ReactFiberReconciler.js @@ -37,7 +37,10 @@ if (__DEV__) { var getComponentName = require('getComponentName'); } -var {findCurrentHostFiber} = require('ReactFiberTreeReflection'); +var { + findCurrentHostFiber, + findCurrentHostFiberWithNoPortals, +} = require('ReactFiberTreeReflection'); var getContextForSubtree = require('getContextForSubtree'); @@ -173,6 +176,9 @@ export type Reconciler = { // Use for findDOMNode/findHostNode. Legacy API. findHostInstance(component: Fiber): I | TI | null, + + // Used internally for filtering out portals. Legacy API. + findHostInstanceWithNoPortals(component: Fiber): I | TI | null, }; getContextForSubtree._injectFiber(function(fiber: Fiber) { @@ -309,5 +315,13 @@ module.exports = function( } return hostFiber.stateNode; }, + + findHostInstanceWithNoPortals(fiber: Fiber): PI | null { + const hostFiber = findCurrentHostFiberWithNoPortals(fiber); + if (hostFiber === null) { + return null; + } + return hostFiber.stateNode; + }, }; }; diff --git a/src/renderers/shared/fiber/ReactFiberTreeReflection.js b/src/renderers/shared/fiber/ReactFiberTreeReflection.js index ce6e0a354bac0..3ea6368a11101 100644 --- a/src/renderers/shared/fiber/ReactFiberTreeReflection.js +++ b/src/renderers/shared/fiber/ReactFiberTreeReflection.js @@ -237,6 +237,41 @@ exports.findCurrentHostFiber = function(parent: Fiber): Fiber | null { return null; } + // Next we'll drill down this component to find the first HostComponent/Text. + let node: Fiber = currentParent; + while (true) { + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } else if (node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === currentParent) { + return null; + } + while (!node.sibling) { + if (!node.return || node.return === currentParent) { + return null; + } + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + // Flow needs the return null here, but ESLint complains about it. + // eslint-disable-next-line no-unreachable + return null; +}; + +exports.findCurrentHostFiberWithNoPortals = function( + parent: Fiber, +): Fiber | null { + const currentParent = findCurrentFiberUsingSlowPath(parent); + if (!currentParent) { + return null; + } + // Next we'll drill down this component to find the first HostComponent/Text. let node: Fiber = currentParent; while (true) {