It listens at the root container and passes a synthetic event that wraps the native event
React listens at the root container, the DOM node you passed to createRoot. This is called event delegation: one listener at the top handles events for all the elements below it. React then calls your handler with a synthetic event. This is a cross-browser wrapper with the same interface as the native event. You can still reach the native event through e.nativeEvent.
The document option is the tempting wrong answer, because it describes React 16. React 16 attached listeners to document and reused event objects, called pooling. React 17 moved delegation to the root and removed pooling. React does not call addEventListener on each button, and it does not generate inline onclick attributes.