10

Lots of new functions released with React 16. One of them is the ReactDOM.createPortal(child, container) API, which is handy for visually breaking out of its container.

However, it seems like that it not only breaks out its container but also breaks the basic html rules which I learned from the first day of web development. The createPortal API let you render your component out of its parent, and break the html structure convention we expected.

In the other hand, we do retrieve more flexibility and now can render DOM in the sibling or else components.

IMO, I don't think this is a good deal to gain more flexibility by trading html convention in. Also the example supplied by official does not convince me.

What I am curious about is: Is there anyone who face any condition that createPortal API is a must?

thanks

fung
  • 641
  • 6
  • 13

3 Answers3

13

The examples in the docs are some of the cases where createPortal is really useful - specifically dialogs, hovercards, and tooltips.

The docs also specifically state:

Note:

It is important to remember, when working with portals, you’ll need to make sure to follow the proper accessibility guidelines.

As an example, the docs show how a modal could be built using createPortal(). You'll notice the modal is created in the #modal-root element, which is a root element alongside the #app-root element. This is a great example of how createPortal() can be used without violating any HTML rules.

<div id="app-root"></div>
<div id="modal-root"></div>
Community
  • 1
  • 1
Brett DeWoody
  • 55,478
  • 28
  • 131
  • 182
10

I ran into another use case a few months ago. Because React 16 portals were not available, I had to use a home-baked portal implementation.

I was creating SVG graphs. All of the lines, paths, and so forth needed to be rendered inside an <svg> element. But I wanted to use HTML to render text labels (for a number of reasons). This meant that an object on the graph and its label would necessarily be in separate parts of the DOM. But with portals, I could still keep all of a graph component's logic together. Here's a fictitious example:

const LabeledPoint = ({ x, y, r, labelText }) => [
    <circle cx={x} cy={y} r={r} />,
    <GraphLabel x={x + 5} y={y}>{labelText}</GraphLabel>,
];

You would use this component inside an <svg> element. The GraphLabel component would use a portal to render labelText in an HTML div element at the same coordinates as that <svg>, using absolute positioning to place it at the correct coordinates.

This way, all of the logic for a single component could be in one place even if I needed to render the actual DOM elements in different places for technical reasons.

Thom Smith
  • 13,599
  • 6
  • 43
  • 83
1

Portals is very useful feature when you need to render your component outside the DOM hierarchy of the parent component.

You define a portal using the following syntax:

ReactDOM.createPortal(child, container) 

The first argument (child) is any renderable React child, such as an element, string, or fragment. The second argument (container) is a DOM element.

See the following tutorial to see how and why to use portals:

https://www.youtube.com/watch?v=lOMU9BeIrO4

SyndicatorBBB
  • 1,667
  • 2
  • 23
  • 42