Normally, a React component renders its output inside the DOM hierarchy of its parent component.

But sometimes, you need to render something outside that hierarchy — like a modal, popup, tooltip, or dropdown menu that should appear above everything else.

This is where React Portals come in. They allow you to render children into a DOM node that exists outside the parent component's DOM hierarchy.

What are Portals?

A Portal allows you to render a React component's output into a different part of the DOM — outside its parent container — while keeping it part of the same React tree.

You create a portal using the createPortal() function from react-dom.


import { createPortal } from "react-dom";

createPortal(child, container);
          
  • child: The React element to render inside the portal.
  • container: The DOM node where the child should be rendered.

Creating Portals

To create a portal, you use the createPortal function from React DOM. This function takes two arguments: the element to render and the DOM node where it should be rendered.

Let's create a simple modal using a portal. First, in your HTML file (usually public/index.html), add a special div for modals:

index.html


<body>
     <div id="root"></div>
     <div id="modal-root"></div>
</body>

Create a Modal Component


import { createPortal } from "react-dom";

function Modal({ children }) {
  const modalRoot = document.getElementById("modal-root");
  return createPortal(children, modalRoot);
}

export default Modal;

Use it in main app


import { useState } from "react";
import Modal from "./Modal";

function App() {
  const [open, setOpen] = useState(false);

  return (
    <div>
      <h2>React Portals Example</h2>
      <button onClick={() => setOpen(true)}>Open Modal</button>

      { open && (
        <Modal>
          <div
            style={{
              position: "fixed",
              top: "0",
              left: "0",
              width: "100%",
              height: "100%",
              background: "rgba(0,0,0,0.6)",
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <div
              style={{
                background: "#fff",
                padding: "20px",
                borderRadius: "10px",
              }}
               >
              <h3>This is a modal rendered using Portal</h3>
              <button onClick={() => setOpen(false)}>Close</button>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}

Explanation

  • We created a Modal component that uses createPortal to render its children into the modal-root div.
  • In the main App component, we manage the modal's open/close state using useState.
  • When the modal is open, we render the Modal component, which displays the modal content above the rest of the app.

Why Use Portals?

Here are some reasons why you might want to use React Portals:

  • Portals allow you to render components outside the normal DOM hierarchy, which is useful for modals, tooltips, dropdowns, and other UI elements that need to be positioned absolutely or outside their parent container.
  • They help avoid issues with z-index stacking contexts and CSS inheritance that can occur when components are nested deeply within the DOM tree.
  • Portals are particularly useful for accessibility features, such as ensuring focus is properly managed within modal dialogs or dropdown menus.

These elements need to “break out” of their parent's overflow or z-index restrictions. Portals allow that — without breaking React's component hierarchy.