React Portals
Find out how to use React Portals
React 16, released in September 2017, introduced Portals.
A portal is a way to render an element outside of its component hierarchy, in a separate component.
When that event is rendered, events happening on it are managed by the React components hierarchy rather than by the hierarchy set by the DOM position of the element.
Hence the name “portal”: an element sits somewhere in the DOM tree that’s outside of the normal React components tree, but the React component tree that includes it is still in charge.
React offers an easy API to do this, ReactDOM.createPortal(), which accepts 2 arguments. The first is the element to render, the second is the DOM element where to render it.
A classic use case for this is modal windows.
A modal to render at full screen must live outside of the element, so it can be properly styled using CSS.
So if a modal is defined as a component:
class Modal extends React.Component {
constructor(props) {
super(props)
this.el = document.createElement('div')
}
componentDidMount() {
document.getElementById('modal').appendChild(this.el)
}
componentWillUnmount() {
document.getElementById('modal').removeChild(this.el)
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el
)
}
}
We can have an App component render it, and all the events happening in the Modal component will be handled by App even though technically the modal is rendered in a different DOM tree:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {showModal: false}
this.handleShow = this.handleShow.bind(this)
this.handleHide = this.handleHide.bind(this)
}
handleShow() {
this.setState({showModal: true})
}
handleHide() {
this.setState({showModal: false})
}
render() {
const modal = this.state.showModal ? (
<Modal>
<div>
The modal <button onClick={this.handleHide}>Hide</button>
</div>
</Modal>
) : ''
return (
<div>
The app <button onClick={this.handleShow}>Show modal</button>
{modal}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
See the full example on https://codepen.io/flaviocopes/pen/KbdagX
download all my books for free
- javascript handbook
- typescript handbook
- css handbook
- node.js handbook
- astro handbook
- html handbook
- next.js pages router handbook
- alpine.js handbook
- htmx handbook
- react handbook
- sql handbook
- git cheat sheet
- laravel handbook
- express handbook
- swift handbook
- go handbook
- php handbook
- python handbook
- cli handbook
- c handbook
subscribe to my newsletter to get them
Terms: by subscribing to the newsletter you agree the following terms and conditions and privacy policy. The aim of the newsletter is to keep you up to date about new tutorials, new book releases or courses organized by Flavio. If you wish to unsubscribe from the newsletter, you can click the unsubscribe link that's present at the bottom of each email, anytime. I will not communicate/spread/publish or otherwise give away your address. Your email address is the only personal information collected, and it's only collected for the primary purpose of keeping you informed through the newsletter. It's stored in a secure server based in the EU. You can contact Flavio by emailing flavio@flaviocopes.com. These terms and conditions are governed by the laws in force in Italy and you unconditionally submit to the jurisdiction of the courts of Italy.