Skip to content

Commit 82e1600

Browse files
nhunzakerSimek
authored andcommitted
Do not bind topLevelType to dispatch (facebook#13618)
* Do not bind topLevelType to dispatch A previous change made it such that all top level event types correspond to their associated native event string values. This commit eliminates the .bind attached to dispatch and fixes a related flow type. * Add note about why casting event.type to a topLevelType is safe * Move interactiveUpdates comment to point of assignment
1 parent 65b03d8 commit 82e1600

File tree

4 files changed

+23
-31
lines changed

4 files changed

+23
-31
lines changed

packages/events/PluginModuleType.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import type {TopLevelType} from './TopLevelEventTypes';
1616

1717
export type EventTypes = {[key: string]: DispatchConfig};
1818

19-
export type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | Touch;
19+
export type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | TouchEvent;
2020

2121
export type PluginName = string;
2222

packages/events/ReactGenericBatching.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import {
2020
let _batchedUpdatesImpl = function(fn, bookkeeping) {
2121
return fn(bookkeeping);
2222
};
23-
let _interactiveUpdatesImpl = function(fn, a, b) {
24-
return fn(a, b);
23+
let _interactiveUpdatesImpl = function(fn, a) {
24+
return fn(a);
2525
};
2626
let _flushInteractiveUpdatesImpl = function() {};
2727

@@ -52,8 +52,8 @@ export function batchedUpdates(fn, bookkeeping) {
5252
}
5353
}
5454

55-
export function interactiveUpdates(fn, a, b) {
56-
return _interactiveUpdatesImpl(fn, a, b);
55+
export function interactiveUpdates(fn, a) {
56+
return _interactiveUpdatesImpl(fn, a);
5757
}
5858

5959
export function flushInteractiveUpdates() {

packages/react-dom/src/events/ReactDOMEventListener.js

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import getEventTarget from './getEventTarget';
2121
import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
2222
import SimpleEventPlugin from './SimpleEventPlugin';
2323
import {getRawEventName} from './DOMTopLevelEventTypes';
24+
import {unsafeCastStringToDOMTopLevelType} from 'events/TopLevelEventTypes';
2425

2526
const {isInteractiveTopLevelEventType} = SimpleEventPlugin;
2627

@@ -48,7 +49,6 @@ function findRootContainerNode(inst) {
4849

4950
// Used to store ancestor hierarchy in top level callback
5051
function getTopLevelCallbackBookKeeping(
51-
topLevelType,
5252
nativeEvent,
5353
targetInst,
5454
): {
@@ -57,6 +57,9 @@ function getTopLevelCallbackBookKeeping(
5757
targetInst: Fiber | null,
5858
ancestors: Array<Fiber>,
5959
} {
60+
// This is safe because DOMTopLevelTypes are always native event type strings
61+
const topLevelType = unsafeCastStringToDOMTopLevelType(nativeEvent.type);
62+
6063
if (callbackBookkeepingPool.length) {
6164
const instance = callbackBookkeepingPool.pop();
6265
instance.topLevelType = topLevelType;
@@ -141,16 +144,13 @@ export function trapBubbledEvent(
141144
if (!element) {
142145
return null;
143146
}
147+
148+
// Check if interactive and wrap in interactiveUpdates
144149
const dispatch = isInteractiveTopLevelEventType(topLevelType)
145150
? dispatchInteractiveEvent
146151
: dispatchEvent;
147152

148-
addEventBubbleListener(
149-
element,
150-
getRawEventName(topLevelType),
151-
// Check if interactive and wrap in interactiveUpdates
152-
dispatch.bind(null, topLevelType),
153-
);
153+
addEventBubbleListener(element, getRawEventName(topLevelType), dispatch);
154154
}
155155

156156
/**
@@ -169,26 +169,20 @@ export function trapCapturedEvent(
169169
if (!element) {
170170
return null;
171171
}
172+
173+
// Check if interactive and wrap in interactiveUpdates
172174
const dispatch = isInteractiveTopLevelEventType(topLevelType)
173175
? dispatchInteractiveEvent
174176
: dispatchEvent;
175177

176-
addEventCaptureListener(
177-
element,
178-
getRawEventName(topLevelType),
179-
// Check if interactive and wrap in interactiveUpdates
180-
dispatch.bind(null, topLevelType),
181-
);
178+
addEventCaptureListener(element, getRawEventName(topLevelType), dispatch);
182179
}
183180

184-
function dispatchInteractiveEvent(topLevelType, nativeEvent) {
185-
interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
181+
function dispatchInteractiveEvent(nativeEvent) {
182+
interactiveUpdates(dispatchEvent, nativeEvent);
186183
}
187184

188-
export function dispatchEvent(
189-
topLevelType: DOMTopLevelEventType,
190-
nativeEvent: AnyNativeEvent,
191-
) {
185+
export function dispatchEvent(nativeEvent: AnyNativeEvent) {
192186
if (!_enabled) {
193187
return;
194188
}
@@ -207,11 +201,7 @@ export function dispatchEvent(
207201
targetInst = null;
208202
}
209203

210-
const bookKeeping = getTopLevelCallbackBookKeeping(
211-
topLevelType,
212-
nativeEvent,
213-
targetInst,
214-
);
204+
const bookKeeping = getTopLevelCallbackBookKeeping(nativeEvent, targetInst);
215205

216206
try {
217207
// Event queue being processed in the same cycle allows

packages/react-dom/src/test-utils/ReactTestUtils.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ const [
4242
runEventsInBatch,
4343
] = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
4444

45-
function Event(suffix) {}
45+
function Event(type) {
46+
this.type = type;
47+
}
4648

4749
let hasWarnedAboutDeprecatedMockComponent = false;
4850

@@ -59,7 +61,7 @@ let hasWarnedAboutDeprecatedMockComponent = false;
5961
*/
6062
function simulateNativeEventOnNode(topLevelType, node, fakeNativeEvent) {
6163
fakeNativeEvent.target = node;
62-
dispatchEvent(topLevelType, fakeNativeEvent);
64+
dispatchEvent(fakeNativeEvent);
6365
}
6466

6567
/**

0 commit comments

Comments
 (0)