Creating Portals

Learn how to render child components into a DOM node outside of the parent DOM hierarchy.

Creating a portal using createPortal()

Creating a portal is relatively simple compared to other concepts we have learned about so far. The component that intends to use the portal has to call the createPortal() method from ReactDOM and pass in a valid component as the first parameter and an existing destination node as the second parameter.

The following example shows a common HTML snippet using portals:

<!doctype html>
<html>
    <head>
        <title>Portals in React</title>
    </head>
    <body>
        <div id="root"><!-- this is where our React App is located -->
        </div>
        <div id="portal"><!-- this is where the content of the portal will be stored -->
        </div>
    </body>
</html>

The following snippet shows the corresponding React App:

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
    return (
        <div>
            <h2>Portals in React</h2>
        </div>
    );
};

ReactDOM.render(<App />, document.querySelector('#root'));

Because our <App /> is placed into the div with the id of root, the <body> of the app now results in this HTML snippet:

<body>
    <div id="root">
        <div>
            <h2>Portals in React</h2>
        </div>
    </div>
    <div id="portal"><!-- this is where the content of the portal will be stored -->
    </div>
</body>

Each additional component or each additional HTML element that is used in the JSX of our App component would end up in the div with the id="root". If we are dealing with a portal, however, the code would resemble the following:

import React from 'react';
import ReactDOM from 'react-dom';

const PortalExample = () => {
    return ReactDOM.createPortal(
        <div>Portal says Hello</div>,
        document.querySelector('#portal')
    );
};

Here, we see the createPortal() method in action. First, we indicate which type of JSX should be rendered. Second, we pass in the type of container, into which the JSX should be rendered. Let’s place this PortalExample component into our App:

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
    return (
        <div>
            <h2>Portals in React</h2>
            <PortalExample />
        </div>
    );
};

ReactDOM.render(<App />, document.querySelector('#root'));

The resulting <body> in the HTML document looks like this:

<body>
    <div id="root">
        <div>
            <h2>Portals in React</h2>
        </div>
    </div>
    <div id="portal">
        <div>Portal says Hello</div>
    </div>
</body>

The portal is rendered into the #portal node instead of the #root node, where all other content, including the component itself, is placed. A portal is rendered once the component mounts and is removed from the DOM if the component containing the portal is removed from the component tree.

Let’s see this in action.

Get hands-on with 1200+ tech skills courses.