Portals render children into a DOM node outside the parent hierarchy — typically document.body. Modals, tooltips, and dropdowns use portals to escape overflow:hidden containers and z-index stacking issues.
createPortal API
createPortal(child, domNode) renders React tree into another DOM node while preserving React event bubbling through the React component hierarchy.
The modal JSX lives logically under <App /> but physically mounts in #modal-root in index.html.
import { createPortal } from 'react-dom';
function Modal({ open, onClose, children }) {
if (!open) return null;
return createPortal(
<div className="overlay" onClick={onClose}>
<div className="modal" onClick={e => e.stopPropagation()}>{children}</div>
</div>,
document.getElementById('modal-root')
);
}
Add <div id="modal-root"></div> to index.html for portal targets.
Events bubble in React tree, not DOM tree — onClick on overlay still works.
Use for modals, drawers, popovers, and full-screen overlays.
Manage focus trap and aria for accessible modals.
Clean up portal target or leave persistent root in HTML.
Portal Patterns
Common portal applications.
Use Case
Target Node
Modal dialog
#modal-root or body
Tooltip
body
Dropdown menu
Near trigger or body
Toast notifications
#toast-root
Full-screen loader
body
Portal Accessibility
Modals need focus trap, role="dialog", aria-modal="true", Escape to close, and return focus to trigger on close. Libraries like Radix UI and Headless UI handle this.
Portals and SSR
Ensure portal target exists before createPortal — check typeof document !== 'undefined' in SSR or render portal only after mount with useEffect.
Common Mistakes
Missing portal root element in HTML.
No focus management in modal portals.
Assuming DOM parent affects React event handlers — it doesn't.
Creating new portal root on every render.
Key Takeaways
Portals render UI into external DOM nodes.
Ideal for modals, tooltips, and overlays.
React events still bubble through component tree.
Implement focus trap and ARIA for modals.
Pro Tip
Reach for Radix Dialog or Headless UI Modal before building portal + focus trap from scratch.
You can render overlays with portals. Next, review refs beyond useRef basics.