Consider the following example:
class GridContainer extends React.Component {
...
render (){
return <div>
<Pagination portalId="portal-id"></>
<Grid ...>
</div>
}
}
class Grid extends React.Component {
...
render (){
return <div>
<div id="portal-id"></>
<table ...>
</div>
}
}
class Pagination extends React.Component {
...
render (){
return return ReactDOM.createPortal(<div>Paginator DOM...</div>, document.getElementById(this.props.portalId));
}
}
Is it safe to render a portal inside other components DOM? I've tested it and it works, but I don't know if this is reliable. The Portals
doc mention that you can render a portal in a DOM node but nothing about components DOM.
Why is this different (speculating here)? while updating the portal parent component, in the reconciliation process the diff might find the inconsistency and remove the portal node.
From my testing, the above doesn't happen but I don't know if I can assume that react handles it. So here comes the Q:
Is it safe to render a portal into another component DOM?
Before React 16.2, you could render only a single DOM node inside the render method. Now you can render multiple DOM nodes. In order to do this, wrap it inside a parent div which essentially makes it a single DOM node with multiple elements inside it. Fragments in React do not deviate much from their literal meaning.
React Portal comes in handy when we need to render child components outside the normal DOM hierarchy without breaking the event propagation's default behavior through the React component tree hierarchy. This is useful when rendering components such as modals, tooltips, popup messages, and so much more.
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. The first argument ( child ) is any renderable React child, such as an element, string, or fragment. The second argument ( container ) is a DOM element.
This is where React Portals are advantageous. React Portals provides the ability for an element to render outside the default hierarchy without compromising the parent-child relationship between components.
Is it safe? Sure, but it probably won't work the way you expect.
First off, you can totally dump dom inside a div
that React created.
I've met several React programmers who would contest this fact, but Reacts design expects and accounts for editing dom directly when necessary. If they didn't, there would be no componentDidUpdate
or React refs
.
This documentation on integration with other libraries is probably the most relevant.
Here's the scoop:
So just create that empty div and leave it alone in render
and React won't mess with it.
Here's the rub; React guarantees nothing about the timing of the renders.
This means that you have no idea if the element will actually be there when Pagination
renders, causing the query to fail and the portal to not display. componentDidUpdate
only works because React specifically runs it after the dom is updated. But render is run before the dom is updated. So if Pagination
is rendered in the same sweep as Grid
that div is likely not mounted yet.
Now the infamous stack overflow Just-Don't-Do-That answer:
Just don't do that. The purpose of portal is to let you render outside the React container while keeping your components inside of Reacts render tree. If you're rendering inside React render tree anyways why don't you just render the components there? (if that statement is confusing I blame you)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With