By default, React renders components inside the DOM hierarchy of their parent component. This works well for most UI elements.
However, certain UI elements like modals, popups, tooltips, and overlays need to visually appear outside their parent container. React Portals solve this problem.
A React Portal lets you render a component into a different DOM node while still keeping it logically connected to the same React component tree.
The createPortal() API is provided by react-dom.
It takes two arguments:
// Core portal syntax
ReactDOM.createPortal(child, container)
First, define multiple root elements in your HTML file.
// index.html portal containers
<div id="root"></div>
<div id="modal-root"></div>
Next, create a reusable Modal component that renders using a portal.
// Modal.js renders children into modal-root
import ReactDOM from "react-dom";
function Modal({ children }) {
const modalRoot = document.getElementById("modal-root");
return ReactDOM.createPortal(children, modalRoot);
}
export default Modal;
Finally, control the modal from the main application component.
// App.js controlling portal visibility with state
import React,{useState} from "react";
import Modal from "./Modal";
function App() {
const [open,setOpen]=useState(false);
return (
<div>
<button onClick={()=>setOpen(true)}>Open Modal</button>
{open && (
<Modal>
<div>
<h4>Portal Modal</h4>
<p>This modal is rendered outside the root DOM</p>
<button onClick={()=>setOpen(false)}>Close</button>
</div>
</Modal>
)}
</div>
);
}
export default App;
Even though the modal is rendered outside the DOM hierarchy, events still propagate through the React component tree.
// Events bubble through React tree, not DOM tree
function Parent() {
const handleClick=()=>alert("Parent clicked");
return (
<div onClick={handleClick}>
<Modal>
<button>Click Me</button>
</Modal>
</div>
);
}
Clicking the button inside the portal still triggers the parent click handler.
The modal is visually displayed outside the root element, preventing layout and overflow issues.
At the same time, it fully participates in React features like state updates, event handling, and context sharing.
z-index to avoid stacking conflictstooltip-root containerGoal: Gain confidence using React Portals to manage advanced UI layouts.