diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 8772b166c4351..cbbbcee185533 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -1126,7 +1126,20 @@ function createPortal( 'Target container is not a DOM element.', ); // TODO: pass ReactDOM portal implementation as third argument - return ReactPortal.createPortal(children, container, null, key); + return ReactPortal.createPortal(children, container, null, key, false); +} + +function createSandboxedPortal( + children: ReactNodeList, + container: DOMContainer, + key: ?string = null, +) { + invariant( + isValidContainer(container), + 'Target container is not a DOM element.', + ); + // TODO: pass ReactDOM portal implementation as third argument + return ReactPortal.createPortal(children, container, null, key, true); } const ReactDOM: Object = { @@ -1291,6 +1304,8 @@ const ReactDOM: Object = { return createPortal(...args); }, + unstable_createSandboxedPortal: createSandboxedPortal, + unstable_batchedUpdates: ReactGenericBatching.batchedUpdates, unstable_deferredUpdates: DOMRenderer.deferredUpdates, diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js index 9d7c305d6fcfb..8054b8c542c6f 100644 --- a/packages/react-reconciler/src/ReactFiber.js +++ b/packages/react-reconciler/src/ReactFiber.js @@ -453,6 +453,7 @@ export function createFiberFromPortal( containerInfo: portal.containerInfo, pendingChildren: null, // Used by persistent updates implementation: portal.implementation, + sandbox: portal.sandbox, }; return fiber; } diff --git a/packages/shared/ReactPortal.js b/packages/shared/ReactPortal.js index c20459c4b62e9..6c60f952cf452 100644 --- a/packages/shared/ReactPortal.js +++ b/packages/shared/ReactPortal.js @@ -17,6 +17,7 @@ export function createPortal( // TODO: figure out the API for cross-renderer implementation. implementation: any, key: ?string = null, + sandbox: ?boolean = false, ): ReactPortal { return { // This tag allow us to uniquely identify this as a React Portal @@ -24,6 +25,7 @@ export function createPortal( key: key == null ? null : '' + key, children, containerInfo, + sandbox, implementation, }; } diff --git a/packages/shared/ReactTreeTraversal.js b/packages/shared/ReactTreeTraversal.js index 7db43fdf2fc27..58593a07f2a02 100644 --- a/packages/shared/ReactTreeTraversal.js +++ b/packages/shared/ReactTreeTraversal.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {HostComponent} from './ReactTypeOfWork'; +import {HostComponent, HostPortal} from './ReactTypeOfWork'; function getParent(inst) { do { @@ -15,6 +15,9 @@ function getParent(inst) { // events to their parent. We could also go through parentNode on the // host node but that wouldn't work for React Native and doesn't let us // do the portal feature. + if (inst && inst.tag === HostPortal && inst.stateNode.sandbox) { + return null; + } } while (inst && inst.tag !== HostComponent); if (inst) { return inst;