Follow up fix to 19452 (#19454)
Dominic Gannaway committed
Jul 27, 2020 at 15:03 UTC
05344faca42468ff7e9225fa26d79fb89377c0cb
3 files changed
+21
-4
packages/react-dom/src/__tests__/ReactDOMEventListener-test.js
+13
-1
@@ -595,7 +595,8 @@ describe('ReactDOMEventListener', () => {
595
const container = document.createElement('div');
596
const innerRef = React.createRef();
597
const outerRef = React.createRef();
598
- const onPlayCapture = jest.fn();
598
+ const onPlayCapture = jest.fn(e => log.push(e.currentTarget));
599
+ const log = [];
600
document.body.appendChild(container);
601
try {
602
ReactDOM.render(
@@ -612,12 +613,23 @@ describe('ReactDOMEventListener', () => {
613
}),
614
);
615
expect(onPlayCapture).toHaveBeenCalledTimes(3);
616
+ expect(log).toEqual([
617
+ outerRef.current,
618
+ outerRef.current.firstChild,
619
+ innerRef.current,
620
+ ]);
621
outerRef.current.dispatchEvent(
622
new Event('play', {
623
bubbles: false,
624
}),
625
);
626
expect(onPlayCapture).toHaveBeenCalledTimes(4);
627
+ expect(log).toEqual([
628
+ outerRef.current,
629
+ outerRef.current.firstChild,
630
+ innerRef.current,
631
+ outerRef.current,
632
+ ]);
633
} finally {
634
document.body.removeChild(container);
635
}
packages/react-dom/src/events/DOMPluginEventSystem.js
-3
@@ -718,9 +718,6 @@ export function accumulateSinglePhaseListeners(
718
const captured = bubbled !== null ? bubbled + 'Capture' : null;
719
const listeners: Array<DispatchListener> = [];
720
721
- // If we are not handling EventTarget only phase, then we're doing the
722
- // usual two phase accumulation using the React fiber tree to pick up
723
- // all relevant useEvent and on* prop events.
721
let instance = targetFiber;
722
let lastHostComponent = null;
723
const targetType = event.type;
packages/react-dom/src/events/plugins/SimpleEventPlugin.js
+8
@@ -43,6 +43,7 @@ import getEventCharCode from '../getEventCharCode';
43
import {IS_CAPTURE_PHASE, IS_NON_DELEGATED} from '../EventSystemFlags';
44
45
import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags';
46
+import {getClosestInstanceFromNode} from '../../client/ReactDOMComponentTree';
47
48
function extractEvents(
49
dispatchQueue: DispatchQueue,
@@ -174,6 +175,13 @@ function extractEvents(
175
// TODO: We may also want to re-use the accumulateTargetOnly flag to
176
// special case bubbling for onScroll/media events at a later point.
177
const accumulateTargetOnly = inCapturePhase && isNonDelegatedEvent;
178
+ // If we are not handling accumulateTargetOnly, then we should traverse
179
+ // through all React fiber tree, finding all relevant useEvent and
180
+ // on* prop events as we traverse the tree. Otherwise, we should
181
+ // only handle the target fiber and stop traversal straight after.
182
+ if (accumulateTargetOnly) {
183
+ targetInst = getClosestInstanceFromNode(((targetContainer: any): Node));
184
+ }
185
186
// We traverse only capture or bubble phase listeners
187
accumulateSinglePhaseListeners(