Event Bubbling Through Portals

Events are bubbled up through the component tree even though the child attached through a portal lies outside the DOM hierarchy of the parent.


RESETRUNFULL
<!DOCTYPE html><html><head></head><body>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="app-root"></div>
<div id="modal-root"></div>
<script type="text/babel">
function Modal(props) {
  return ReactDOM.createPortal(
    props.children,
    document.getElementById('modal-root'));
}
function Parent() {
  return (
    <div onClick={() => alert('clicked')}>
      <Modal>
        <Child />
      </Modal>
    </div>
  );
}
function Child() {
  // The click event on this button will bubble up to parent,
  // because there is no 'onClick' attribute defined
  return (<div className="modal">
    <button>Click</button>
  </div>);
}
const root = ReactDOM.createRoot(document.getElementById('app-root'));
root.render(<Parent />);
</script></body></html>

In addition to event bubbling, contexts work similarly, affecting descendent components that are not attached directly to the parent DOM node.