What Are Portals?
Imagine you're building a modal dialog. You want it to appear on top of everything else, but your component is nested deep in the DOM tree. React portals are like teleportation devices โ they let you render a component's content somewhere else in the DOM.
Portals let you render children into a different part of the DOM tree, while keeping the React component tree intact. Your modal can live inside a Modal component in your code, but render directly into the document body.
Rendering Outside Parent DOM
To create a portal, you use the ReactDOM.createPortal function. You pass it two arguments: the JSX you want to render, and the DOM node where you want to render it. It's like giving your component a teleportation coordinates.
The key insight is that while the rendered content appears elsewhere in the DOM, it still behaves as if it's part of the React component tree. Events bubble up through the React tree, not the DOM tree. It's the best of both worlds.
import { useState } from "react";
import { createPortal } from "react-dom";
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
return createPortal(
<div className="modal-overlay">
<div className="modal">
{children}
<button onClick={onClose}>Close</button>
</div>
</div>,
document.body
);
}
Try it Yourself โ
Use Cases: Modals and Tooltips
Modals are the classic portal use case. You want them to cover the entire screen, but your Modal component might be nested inside a page layout. Portals let you render the modal content directly into the body, giving you full control over its positioning.
Tooltips and popovers are another great example. They need to appear above other content, but they're triggered by elements deep in the DOM. Portals let you keep the tooltip logic close to its trigger while rendering it at the top level.
function Tooltip({ children, text }) {
const [show, setShow] = useState(false);
return (
<div
onMouseEnter={() => setShow(true)}
onMouseLeave={() => setShow(false)}
>
{children}
{show && createPortal(
<div className="tooltip">{text}</div>,
document.body
)}
</div>
);
}
Try it Yourself โ
Event Bubbling in Portals
Here's something cool: even though portal content renders in a different DOM location, events still bubble up through the React component tree. If you click a button inside a portal, the onClick handler in the parent component will still fire.
This is different from regular DOM event bubbling. React portals give you the DOM placement flexibility you need while maintaining the component relationships you've built. It's like having your cake and eating it too.