diff --git a/packages/react-dom/src/client/ReactDOMComponent.js b/packages/react-dom/src/client/ReactDOMComponent.js
index 5cc6981d82aad..7e20c5452badd 100644
--- a/packages/react-dom/src/client/ReactDOMComponent.js
+++ b/packages/react-dom/src/client/ReactDOMComponent.js
@@ -59,7 +59,7 @@ import {
import {getListenerMapForElement} from '../events/DOMEventListenerMap';
import {
addResponderEventSystemEvent,
- removeActiveResponderEventSystemEvent,
+ removePassiveResponderEventSystemEvent,
} from '../events/ReactDOMEventListener.js';
import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
import {
@@ -1360,7 +1360,7 @@ export function listenToEventResponderEventTypes(
const passiveKey = targetEventType + '_passive';
const passiveListener = listenerMap.get(passiveKey);
if (passiveListener != null) {
- removeActiveResponderEventSystemEvent(
+ removePassiveResponderEventSystemEvent(
document,
targetEventType,
passiveListener,
diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js
index 040029c46d7f4..13f40eb95deb7 100644
--- a/packages/react-dom/src/events/ReactDOMEventListener.js
+++ b/packages/react-dom/src/events/ReactDOMEventListener.js
@@ -105,6 +105,7 @@ export function addResponderEventSystemEvent(
} else {
eventFlags |= IS_ACTIVE;
}
+ let fbListener;
// Check if interactive and wrap in discreteUpdates
const listener = dispatchEvent.bind(
null,
@@ -113,30 +114,34 @@ export function addResponderEventSystemEvent(
document,
);
if (passiveBrowserEventsSupported) {
- addEventCaptureListenerWithPassiveFlag(
+ fbListener = addEventCaptureListenerWithPassiveFlag(
document,
topLevelType,
listener,
passive,
);
} else {
- addEventCaptureListener(document, topLevelType, listener);
+ fbListener = addEventCaptureListener(document, topLevelType, listener);
}
- return listener;
+ return fbListener || listener;
}
-export function removeActiveResponderEventSystemEvent(
+export function removePassiveResponderEventSystemEvent(
document: Document,
topLevelType: string,
listener: any => void,
) {
- if (passiveBrowserEventsSupported) {
- document.removeEventListener(topLevelType, listener, {
- capture: true,
- passive: false,
- });
+ if (listener.remove) {
+ listener.remove();
} else {
- document.removeEventListener(topLevelType, listener, true);
+ if (passiveBrowserEventsSupported) {
+ document.removeEventListener(topLevelType, listener, {
+ capture: true,
+ passive: true,
+ });
+ } else {
+ document.removeEventListener(topLevelType, listener, true);
+ }
}
}
diff --git a/packages/react-dom/src/events/__tests__/DeprecatedDOMEventResponderSystem-test.internal.js b/packages/react-dom/src/events/__tests__/DeprecatedDOMEventResponderSystem-test.internal.js
index c3fa398e83766..62fda3edfb5c1 100644
--- a/packages/react-dom/src/events/__tests__/DeprecatedDOMEventResponderSystem-test.internal.js
+++ b/packages/react-dom/src/events/__tests__/DeprecatedDOMEventResponderSystem-test.internal.js
@@ -948,4 +948,39 @@ describe('DOMEventResponderSystem', () => {
document.body.removeChild(domNode);
expect(onEvent).toBeCalled();
});
+
+ it('event upgrading should work correctly', () => {
+ let eventResponderFiredCount = 0;
+ const buttonRef = React.createRef();
+
+ const TestResponder = createEventResponder({
+ targetEventTypes: ['click'],
+ onEvent: (event, context, props, state) => {
+ eventResponderFiredCount++;
+ if (!state.addedRootEventTypes) {
+ context.addRootEventTypes(['click_active']);
+ }
+ state.addedRootEventTypes = true;
+ },
+ });
+
+ function Test() {
+ const listener = React.DEPRECATED_useResponder(TestResponder, {});
+
+ return (
+
+ );
+ }
+
+ ReactDOM.render(, container);
+ expect(container.innerHTML).toBe('');
+
+ let buttonElement = buttonRef.current;
+ dispatchClickEvent(buttonElement);
+ expect(eventResponderFiredCount).toBe(1);
+ dispatchClickEvent(buttonElement);
+ expect(eventResponderFiredCount).toBe(2);
+ });
});