Rendering and data flow
Render an overlay with a portal
Place a component child in another DOM container while keeping it in the same React component tree.
A portal renders children into another DOM node while keeping them in the same React tree.
import { createPortal } from 'react-dom'
function Modal({ children }) {
const modalRoot = document.getElementById('modal-root')
return createPortal(children, modalRoot)
}
This is useful when an overlay must escape a container’s clipping or stacking context. The modal DOM can live near the end of body while its component remains a child of the page in React.
Context still follows the React tree. React events also propagate through React parents, not only DOM parents. A click inside the portal still bubbles through your React component hierarchy the way you expect.
A portal only changes placement. It does not create accessible dialog behavior on its own.
A modal still needs an accessible name, focus moved inside, Escape and close-button handling, background interaction rules, and focus returned to the opener. Without those pieces, you have a positioned box, not a usable dialog.
Use the native dialog element where it fits. It provides useful browser behavior that a generic portal does not, like built-in modal semantics and backdrop handling in modern browsers.
Portals are common for tooltips, dropdown menus, and full-screen overlays. Any time parent CSS would clip or hide your UI, a portal is worth considering before fighting overflow: hidden on every ancestor.
Add a #modal-root div to your HTML if the project does not have one yet. Without a target node, createPortal has nowhere to render and the overlay will not appear.
Inspect the component tree and DOM tree for a portal. Confirm the same content has different parents in the two views. In React DevTools you should see Modal under your page component. In the Elements panel the same markup should sit under #modal-root near body.
Lesson completed