A modal rendered where it logically belongs is trapped by any ancestor with overflow: hidden, a transform, or a z-index stacking context — and moving it in the tree means losing its props and its place in the component hierarchy.
ReactDOM.createPortal(
{children},
document.getElementById('modal-root')
);
The DOM node moves and the React tree does not, which is the whole trick: context still flows, and an event fired inside the portal still bubbles to its React parent rather than to its DOM parent. That last part surprises people in both directions — a click inside the modal reaches an onClick on the logical parent, which is usually what you want and occasionally exactly not.