React Portals
Render children into a DOM node outside the parent hierarchy
Overview
A portal renders children into a DOM node that lives outside the parent component's DOM tree, while keeping them in the React tree. This is ideal for modals, tooltips, and toasts that must escape a parent's overflow: hidden or z-index stacking context. Events still bubble through the React tree, not the DOM position.
Syntax / Usage
Call createPortal(children, domNode) and return its result from your component.
import { createPortal } from 'react-dom'
function Modal({ children, onClose }: { children: React.ReactNode; onClose: () => void }) {
return createPortal(
<div className="overlay" onClick={onClose}>
<div className="dialog" onClick={(e) => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
)
}
Examples
Render into a dedicated container element created once via a ref:
import { useRef, useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
function Toast({ message }: { message: string }) {
const [mounted, setMounted] = useState(false)
const nodeRef = useRef<HTMLDivElement | null>(null)
useEffect(() => {
const node = document.createElement('div')
document.body.appendChild(node)
nodeRef.current = node
setMounted(true)
return () => {
document.body.removeChild(node)
}
}, [])
if (!mounted || !nodeRef.current) return null
return createPortal(<div className="toast">{message}</div>, nodeRef.current)
}
Because events propagate through the React tree, a click inside a portalled modal still bubbles to the parent's onClick handler even though the DOM node lives on document.body.
Common Mistakes
- Rendering a portal during SSR where
documentis undefined—guard with a mounted check - Forgetting to remove a dynamically created container, leaking DOM nodes
- Assuming events bubble by DOM position instead of React tree position
- Losing focus management and accessibility—portals still need focus traps and
ariaroles - Recreating the target container on every render instead of once in an effect
See Also
components use-ref use-effect