Ever heard about React Portals? Maybe you never knew when you should use React Portals. Well if you've come to learn about React Portals and their use case, you have come to the right article!
Normally we are constrained to a hierarchical structure in which elements are mounted in the DOM tree as the child of the nearest parent node.
React Portals enable us to break out of this enforced hierarchical structure.
What are React Portals?
According to the React documents description, portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
Simply put, React Portals allow us to render elements outside of the parent elements' context.If you don't quite understand why you would want functionality like this or how you would apply it, don't worry, I've got an example for you!
How can I use React Portals?
The best learning example for React Portals that helped me understand situations in which they are helpful, was when I was thinking about modals.
Let's briefly talk about modal behavior so we can understand why I have come to thinking about using React Portals.
A modal's purpose is to disrupt the present flow the user is going through in a website. When a modal displays to the user, the webpage typically gets blocked via a gray background and container that is completely outside of the context of the website. Given the purpose and behavior of modal's, we don't want it to be limited by *where* it is being rendered. This is where the React Portal becomes handy!Let's imagine we have a React Component Modal that we want to use in App. I intend to add a lot of nested divs to demonstrate how portals work.
import React from 'react';import { createPortal } from 'react-dom';// Componentsimport Modal from './primitives/Modal';export class App extends React.Component {constructor (props) {super(props);this.state = {mounted: false};}componentDidMount () {this.setState({mounted: true});this.container = document.getElementById("appRoot");}render() {const { mounted = false } = this.state;return (<div id="appRoot"><div><div>I am a super nested div...<div>{ mounted ? createPortal(<Modal />, this.container) : null }</div></div></div></div>);}};
Notice the nesting I've added below appRoot. The modal is a child within 4 wrapping divs, yet it will render as a child of appRoot (our parent most element). This nesting will serve to demonstrate the power of React Portals.
Let's take a look at how this written logic renders on our page. Notice in the attached image that the div with outerModal class is a child of appRoot. But wait, I put the logic to render the modal within 3 nested divs within appRoot. How can that be?
Well, I added the createPortal function in the above code sample, and said I would like the Modal component to be a child of this.container
, which in our case is the div with id appRoot!
You might be wondering why having this functionality is useful. A big problem with modals rendering in quite nested parts of the DOM, is styling inheritance. We might have some styles that we don't want affecting our modal, so with portals allowing us to specify where we want it to render, we can avoid these issues.
For a concrete example, let's say we have this style defined on a nested element:
overflow: hidden
and our modal was rendering as a child of said element, overflow: hidden
will affect our modals styling and we would not be able to change it without removing that style!
One last thing you might be wondering is why I am checking for mounting first. Without checking mounting, the function createPortal causes a thrown error Target container is not DOM element.
Why does this happen? Because the function createPortal is expecting as input the child and the parent container of the child. Problem is, before mounting occurs, there is no parent container available for the child! This is why I added the simple check for mounting. We know with certainty that there is a parent container to add the child to by checking for that lifecycle stage occurrence. Therefore we arrive at a primary rule when using portals.
Other details are nicely handled, everything you would normally expect for a React Component applies to portals. This is because the DOM hierarchy is the only changed aspect when using portals, not the React hierarchy.
Therefore, lifecycle is still controlled by React, event bubbling is as expected, keyboard events, you name it!
Conclusion
React portals are useful in circumstances where you need to render DOM elements in a location besides its immediate parent. Modals are just one example where it is useful to have the control portals give us where the parent element is concerned. I hope you found this article useful and now feel confident with React Portals!
Happy coding everyone!
Remember, developers are creatures that turn coffee into code. So I'd very much appreciate if you bought me a coffee! I’m a new writer and I will be posting very frequently on my findings and learnings in the tech industry and beyond. Join my newsletter if you would like to stay tuned!
Thanks for reading again! ❤️
Understand Open Graph Dynamic Image Meta Tags | 1 |
Pros and Cons of Caching Data in Software | 2 |
How to build a Modal in ReactJS (Part One) | 3 |