React 16 attached every handler to document and 17 attaches them to the root container, which changes what stopPropagation can prevent.
// worked in 16: the React handler ran at document level
// first, so stopPropagation() prevented this listener.
document.addEventListener('click', onOutsideClick)
// in 17: the React handler runs at #root, the event still
// bubbles to document, and the menu closes on every click.
// the fix that works on both, and is better anyway
document.addEventListener('pointerdown', onOutsideClick, true)
The change exists to make two React versions coexist on one page, and it is a behaviour change for anything mixing React with a document-level listener — which is every close-on-outside-click implementation and most integrations with a non-React widget. Using the capture phase makes the ordering explicit rather than dependent on where React attaches, which is the version that will keep working. jsdom does not model this faithfully, so unit tests pass and browser tests fail.