Portals
Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
ReactDOM.createPortal(child, container)The first argument (child) is any renderable React child, such as an element, string, or fragment. The second argument (container) is a DOM element.
Usage
Normally, when you return an element from a component's render method, it's mounted into the DOM as a child of the nearest parent node:
render() {
// React mounts a new div and renders the children into it
return (
<div>
{this.props.children}
</div>
);
}However, sometimes it's useful to insert a child into a different location in the DOM:
render() {
// React does *not* create a new div. It renders the children into `domNode`.
// `domNode` is any valid DOM node, regardless of its location in the DOM.
return ReactDOM.createPortal(
this.props.children,
domNode
);
}A typical use case for portals is when a parent component has an overflow: hidden or z-index style, but you need the child to visually "break out" of its container. For example, dialogs, hovercards, and tooltips.
Note:
When working with portals, remember that managing keyboard focus becomes very important.
For modal dialogs, ensure that everyone can interact with them by following the WAI-ARIA Modal Authoring Practices.
Event Bubbling Through Portals
Even though a portal can be anywhere in the DOM tree, it behaves like a normal React child in every other way. Features like context work exactly the same regardless of whether the child is a portal, as the portal still exists in the React tree regardless of position in the DOM tree.
This includes event bubbling. An event fired from inside a portal will propagate to ancestors in the containing React tree, even if those elements are not ancestors in the DOM tree. Assuming the following HTML structure:
A Parent component in #app-root would be able to catch an uncaught, bubbling event from the sibling node #modal-root.
Catching an event bubbling up from a portal in a parent component allows the development of more flexible abstractions that are not inherently reliant on portals. For example, if you render a <Modal /> component, the parent can capture its events regardless of whether it's implemented using portals.
Last updated
Was this helpful?