React
Event bubbling
Learn that events still reach the component from a portal.
Event propagation
Although a portal renders elsewhere, it stays a child of its parent in the React tree. So events (like click, change) bubble to the parent.
This is useful for modals: when a button inside the modal is clicked, the event goes to the parent which can update state. Without a portal, the event would stay in the modal's DOM branch.
To stop propagation, use e.stopPropagation(); this prevents a content click from reaching the backdrop.
Using stopPropagation
In a modal, clicking the content box should not trigger the backdrop. The content box's click handler calls e.stopPropagation(); this stops the event from reaching the backdrop, so the modal does not close.
But clicking the backdrop directly lets the event propagate and calls onClose. This distinction lets the user interact with content without accidentally closing the modal.
The same pattern is used in dropdowns: clicking inside does not close, clicking outside does.
Exercise Modal stopPropagation
Complete the skeleton below. Write a Modal component; take { open, onClose, children }, return null if open is false, otherwise use createPortal to render an outer <div className="modal" onClick={onClose}> with an inner <div className="content" onClick={(e) => e.stopPropagation()}>{children}</div>. Export it.
Show example solution
import { createPortal } from "react-dom";
function Modal({ open, onClose, children }) {
if (!open) return null;
return createPortal(
<div className="modal" onClick={onClose}>
<div className="content" onClick={(e) => e.stopPropagation()}>{children}</div>
</div>,
document.getElementById("modal-root")
);
}
export default Modal;
Test yourself
-
Where do portal events bubble?
- To the DOM parent node
- To the React parent component
- Body'ye
- Nowhere
Show answer
To the React parent component — Portal events bubble to the React parent.
-
Stop event
function Box({ children }) {
return <div onClick={(e) => { e.____(); handleClick(); }}>{children}</div>;
}
Show answer
function Box({ children }) {
return <div onClick={(e) => { e.stopPropagation(); handleClick(); }}>{children}</div>;
}
-
Event bubbling: match the terms
- createPortal
- Renders into another node
- stopPropagation
- Stops the event
- React tree
- Event path
- onClose
- Close handler
Next lesson: Summary - Portal