A portal allows you to render an element of a child component outside the DOM hierarchy by creating another top-level tree and injecting this component inside it.
In general, portals are used when we want to position or style an element correctly. Sometimes, a modal is in a child that is nested a dozen level-deep. Then, modifying the style of the child without breaking the one from the parent can be really difficult… This is why we want to take this modal out of this hierarchy so we can manipulate it without affecting the parents.
Well, let’s create a simple React app that will display a modal when we click on a button. The whole app is in the root DOM hierarchy but the modal will be outside these three.
First, go to your index.html. You can see that there is already a div which contains an ‘app-root’. That’s the main DOM tree. But we want to display our modal outside of this tree. So let’s create another top-level div and call it ‘modal-root’.
Then, in our App.js file, we will have a button that will toggle the modal and another button inside the modal, that will close it. We need to create and render these first.
If you have carefully read the code, you can see that the modal that will be displayed is between the <Modal> tag. So we have to create this component, which will be the one that creates the portal to our modal-root div.
To give you a brief explanation, the createPortal() function takes two arguments. The first one is the child that will be rendered. In our case, that’s the Modal. The second argument is the container which represents the DOM element. That’s the modal-root.
Now the only thing left to do is to not forget to render the parent (In our case, that is the <App />) into the root div. Check on line 39 of the code now.
Like the createPortal() function, The render() function from the reactDOM here takes also two arguments. The first argument is the whole application, represented by the <App> tag. The second one is also a container. Here it is our main root.
And you have finished!
The modal is no longer nested inside our main DOM hierarchy. You can style it without worrying about the parent(s).