React v16 introduced a new feature called portals. Portals provide a quick and easy way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. React render the entire app under a single DOM node — the app root. But what if you want to render children outside the root DOM node? that's when you use Portals.
Two examples for doing this are when the parent element has styling (like a z-index pushing it to the front of the page or an overflow: hidden) but you want the child to visually appear on top of its container.
A portal can be anywhere in the DOM tree, it behaves like a normal React child in every other way. Features like context work exactly the same regardless of whether the child is a portal, as the portal still exists in the React tree regardless of position in the DOM tree. This includes event bubbling. An event fired from inside a portal will propagate to ancestors in the containing React tree, even if those elements are not ancestors in the DOM tree.
I recommend it creating a component, and then using every time we need to. First, we need to create a DOM element (like the root element we created to append the app) in your index.html
, this is where all the portals components are going to be attached.
<div id="portal-components"></div>
<div id="root">
Then create the Portal component
import { PureComponent } from 'react'
import ReactDOM from 'react-dom'
const rootElement = document.getElementById('portal-components')
class Portal extends PureComponent {
constructor(props) {
super(props)
this.el = document.createElement('div')
}
componentDidMount() {
rootElement.appendChild(this.el)
}
componentWillUnmount() {
rootElement.removeChild(this.el)
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el
)
}
}
export default Portal
Then use it like so
<Portal>
{Everithing here is going to be attachaded outside the root DOM node}
</Portal>
When using Portals, everything inside the <Portal>
component is going to be placed absolute to the screen, I recommend using CSS fixed positions to adjust alignments.