Through Portals in React

Interplanetary travel is not exactly available or popular yet. Technically speaking, we can run into similar difficulties when travelling between different DOM structures in SPA applications. Today, let us look at how React solves this problem.

React portals

From this article you will learn:

  • What are Portals in React?
  • When is the Portal mechanism most often useful?
  • How do we open new Portals?
  • Does React have full control over a component rendered through a Portal?

A classic application built with React bases its structure on a single DOM node. In other words, in the HTML file we create one element, most often a div, assign an id to it, and then tell React that it should render the DOM tree inside that element. This construction is very convenient from the library's own perspective. It is easy to recreate the structure itself and detect changes that appear within it.

Sometimes, however, we may find ourselves in a situation where we do not want to create new elements inside our React tree structure. At the same time, building a second application would not be an optimal solution if both applications had to share data and state. Good examples are all kinds of modals, notifications, and elements that we need to move into new windows. We usually need modals and notifications at the highest level of the application, high in the DOM structure, so that they are not covered by other elements. New browser windows are a completely different topic - they have their own structure, not connected to the current page.

Portals

Portals in React are nothing more than a mechanism that lets us render React elements outside the place in the structure where they would normally be rendered. In fact, they let us render our elements anywhere in the DOM (Document Object Model), and even inside dependent windows. Thanks to the Window.opener and Document.referrer properties, we can access the windows that opened a given window and, in a sense, manage it. Portals can also be useful when a component's styling limits the possibility of rendering a given element correctly, for example when the component has overflow: hidden or z-index set.

What is important, an element rendered through the Portal mechanism still remains under React's full control. What is more, from the application's perspective, it behaves as if it had been rendered in the place where it would normally land in the structure. This gives us a whole set of possibilities, such as sharing state, accessing props passed down through the tree, or using the Context API. It is also worth noting that event bubbling will work the same way as without a Portal, meaning that events fired inside a Portal will propagate up through the React tree structure.

Portals affect only the structure of the DOM tree. They do not affect the React component tree.

Opening a Portal

There is actually no magic here. Advanced knowledge of quantum physics is not required either. The createPortal method provided by the react-dom library is used to open portals.

js
import { createPortal } from 'react-dom';

const Modal = ({ children }) => {
	return createPortal(
		<div>{children}</div>,
		document.getElementById('modal'),
	)
}

It is worth paying attention to the fact that the method opening a Portal accepts two arguments: the component we render and the node where we will place it. Importantly, such an element should be prepared earlier. We can account for that and add it directly to our original HTML. Of course, everything depends on our needs and on the use case for which we want to use Portals. Elements in which we want to open Portals can also be created dynamically.

html
<body>
	<div id="app"></div> /* here we render the React application */
	<div id="modal"></div> /* here we render our modal by using a Portal */
</body>

Summary

As we can see, React Portals are a simple tool to use, but a very useful one in the context of more complex applications. We should remember that although our component will be passed through a Portal to a new place in the DOM structure, it will still remain in the React component tree and follow the same rules as an ordinary React component.

It seems to me that this is one of several underestimated React features, just like the useLayoutEffect hook. Many people forget they exist, while more than once they could solve some of our problems.

Sources

Share this article:

Comments (0)

    No one has posted anything yet, but that means.... you may be the first.

You may be interested in

If this article interested you, check out other materials related to it thematically. Below you will find articles and podcast episodes authored by me, as well as books I recommend that expand on this topic.

NextJS i co dalej by Mateusz Jabłoński
Podcast
01 June 2023

NextJS i co dalej

NextJS wprowadził React'a na nowe ścieżki. Śmiało można powiedzieć, że twórcy Next'a zmieniają frontend. O tym rozmawiamy w piątym odcinku podcastu Piwnica IT.

Posłuchaj
Matryoshka Dolls by Frankenvrij
Article
2021-08-13

Currying

Functional programming is almost as popular as object-oriented programming. Many concepts from object-oriented programming have entered programming in general so deeply that sometimes we no longer even notice where a given approach comes from. Functional programming also has its interesting concepts, and currying is one of them. In this article I use examples to show how currying works and what problems it can help us solve.

Read more
Data binding by
Article
2023-03-26

What Is Data Binding?

Data binding is often mentioned when discussing Angular or React. What is it? Today I would like to explain this concept using examples.

Read more

Zapisz się do newslettera

Bądź na bieżąco z nowymi materiałami, ćwiczeniami i ciekawostkami ze świata IT. Dołącz do mnie.