When to Avoid React Portals in React
React Portals are a powerful feature that allows you to render child components into a DOM node outside of the parent component’s DOM hierarchy. While they are highly effective for elements like modals, tooltips, and dropdowns, they are not a universal solution for layout challenges. This article explores the specific scenarios where you should avoid using React Portals, focusing on accessibility risks, event bubbling complications, styling limitations, and unnecessary architectural complexity.
1. When Keyboard Navigation and Accessibility are Broken
Although a portal renders a component outside its parent DOM node, it still resides in its original position within the React virtual DOM tree. This mismatch creates a disconnect between the physical DOM order and the React component structure.
If you use a portal for interactive elements, screen readers and keyboard users may experience disruptive behavior. The natural tab focus order follows the physical DOM. If a user tabs into a portaled modal, and then tabs out, their focus might jump to an unexpected part of the page instead of returning to the trigger element. If you cannot implement robust manual focus trapping and aria-attributes to manage this behavior, you should avoid portals and stick to standard DOM positioning.
2. When Event Bubbling Causes Side Effects
React Portals preserve React’s virtual DOM event propagation behavior. This means an event fired from inside a portal will bubble up to its React ancestors, even if those ancestors are completely different branches in the actual HTML DOM.
For example, if you place a portaled modal inside a parent component
that has an onClick handler, clicking inside the modal will
trigger the parent’s click event. If this behavior is undesired and
causes bugs—such as closing a form or submitting data prematurely—you
should avoid portals. Managing these issues requires constantly calling
e.stopPropagation(), which can make your codebase fragile
and difficult to maintain.
3. When You Rely on Parent CSS Context
Portaled elements are detached from their React parent’s physical DOM
tree and are typically mounted directly under document.body
or another root-level node. Consequently, the portaled component loses
access to any CSS styles that depend on nesting or parent-child
selectors.
If your application relies heavily on scoped styles, CSS Modules, or
CSS-in-JS libraries that inherit variables and themes from parent
containers, using a portal will break these styles. If you find yourself
duplicating CSS rules or forcing global styles just to style a portaled
component, it is better to avoid portals and use standard CSS
positioning (like position: absolute or
position: fixed) within the local DOM tree.
4. When Simple CSS Can Achieve the Same Goal
Developers often default to React Portals for elements like tooltips, dropdown menus, or hover cards. However, introducing a portal adds complexity to your React tree and increases DOM manipulation overhead.
If a UI element can be easily positioned using modern CSS—such as
flexbox, grid, position: absolute, or the newer CSS anchor
positioning API—you should avoid using React Portals. Portals should be
reserved for components that genuinely need to break out of containers
with overflow: hidden or restrictive z-index
stacking contexts. If those CSS constraints do not exist in your current
layout, a portal is overengineering.