Modals and dialogs
A dialog needs to escape an ancestor's clipping or stacking context.
React 19+ · Type Alias
createPortal renders React children into a different part of the DOM while preserving their place in the React tree. It is commonly used for UI such as modals that must escape container boundaries.
createPortal returns a React node that places renderable children inside an existing DOM node. The portal changes where those nodes appear physically, but the content remains a child of the component that created it for React behavior such as context and event propagation.
createPortal(children, domNode, key?)| Name | Type | Description |
|---|---|---|
children | ReactNode | Any React-renderable content, such as JSX, a fragment, string, number, or an array of these. |
domNode | Element | An already-existing DOM node that receives the rendered children. |
key | string | number | null | undefined | An optional key for the portal. |
A React node that can be rendered in JSX or returned from a React component; React places its children inside the supplied DOM node.
import { createPortal } from "react-dom";
export default function Modal({ open, children }) {
if (!open) return null;
return createPortal(
<div role="dialog" aria-modal="true">
{children}
</div>,
document.body
);
}This component places the dialog under document.body while keeping it in the React tree.
A dialog needs to escape an ancestor's clipping or stacking context.
A transient notification should mount in a document-level host.
A menu or tooltip must render outside an overflow-constrained container.
Use createPortal from react-dom with renderable children and an existing DOM node. React inserts the children into that node while the portal remains part of the originating component's React tree.
Follow-up: What changes when the target element changes? React recreates the portal content when a different DOM node is supplied during an update.
A portal changes only the physical DOM placement. The JSX still behaves as a child of the component that renders it, so React relationships are preserved.
Follow-up: Why are portals useful for dialogs? They let dialog markup escape clipping or stacking containers while remaining owned by the dialog component.
The children argument accepts anything React can render, including JSX, fragments, strings, numbers, or arrays of these. The domNode argument identifies the already-existing destination node.
Follow-up: What should be checked before rendering into a destination? Ensure the destination exists before the portal is rendered and avoid changing it unnecessarily.
ReactNodeFragmentreact-domcreatePortal