@samitouri / QOS-React / commits / 0c9c591bfb

Do not bind topLevelType to dispatch (#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

Nathan Hunzaker committed Sep 14, 2018 at 16:08 UTC 0c9c591bfb4c280d69bc9c1dd692ab0028bb0f8e
4 files changed +23 -31
packages/events/PluginModuleType.js
+1 -1
@@ -16,7 +16,7 @@ import type {TopLevelType} from './TopLevelEventTypes';
16
17 export type EventTypes = {[key: string]: DispatchConfig};
18
19 -export type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | Touch;
19 +export type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | TouchEvent;
20
21 export type PluginName = string;
22
packages/events/ReactGenericBatching.js
+4 -4
@@ -20,8 +20,8 @@ import {
20 let _batchedUpdatesImpl = function(fn, bookkeeping) {
21 return fn(bookkeeping);
22 };
23 -let _interactiveUpdatesImpl = function(fn, a, b) {
24 - return fn(a, b);
23 +let _interactiveUpdatesImpl = function(fn, a) {
24 + return fn(a);
25 };
26 let _flushInteractiveUpdatesImpl = function() {};
27
@@ -52,8 +52,8 @@ export function batchedUpdates(fn, bookkeeping) {
52 }
53 }
54
55 -export function interactiveUpdates(fn, a, b) {
56 - return _interactiveUpdatesImpl(fn, a, b);
55 +export function interactiveUpdates(fn, a) {
56 + return _interactiveUpdatesImpl(fn, a);
57 }
58
59 export function flushInteractiveUpdates() {
packages/react-dom/src/events/ReactDOMEventListener.js
+14 -24
@@ -21,6 +21,7 @@ import getEventTarget from './getEventTarget';
21 import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
22 import SimpleEventPlugin from './SimpleEventPlugin';
23 import {getRawEventName} from './DOMTopLevelEventTypes';
24 +import {unsafeCastStringToDOMTopLevelType} from 'events/TopLevelEventTypes';
25
26 const {isInteractiveTopLevelEventType} = SimpleEventPlugin;
27
@@ -48,7 +49,6 @@ function findRootContainerNode(inst) {
49
50 // Used to store ancestor hierarchy in top level callback
51 function getTopLevelCallbackBookKeeping(
51 - topLevelType,
52 nativeEvent,
53 targetInst,
54 ): {
@@ -57,6 +57,9 @@ function getTopLevelCallbackBookKeeping(
57 targetInst: Fiber | null,
58 ancestors: Array<Fiber>,
59 } {
60 + // This is safe because DOMTopLevelTypes are always native event type strings
61 + const topLevelType = unsafeCastStringToDOMTopLevelType(nativeEvent.type);
62 +
63 if (callbackBookkeepingPool.length) {
64 const instance = callbackBookkeepingPool.pop();
65 instance.topLevelType = topLevelType;
@@ -141,16 +144,13 @@ export function trapBubbledEvent(
144 if (!element) {
145 return null;
146 }
147 +
148 + // Check if interactive and wrap in interactiveUpdates
149 const dispatch = isInteractiveTopLevelEventType(topLevelType)
150 ? dispatchInteractiveEvent
151 : dispatchEvent;
152
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);
154 }
155
156 /**
@@ -169,26 +169,20 @@ export function trapCapturedEvent(
169 if (!element) {
170 return null;
171 }
172 +
173 + // Check if interactive and wrap in interactiveUpdates
174 const dispatch = isInteractiveTopLevelEventType(topLevelType)
175 ? dispatchInteractiveEvent
176 : dispatchEvent;
177
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);
179 }
180
184 -function dispatchInteractiveEvent(topLevelType, nativeEvent) {
185 - interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
181 +function dispatchInteractiveEvent(nativeEvent) {
182 + interactiveUpdates(dispatchEvent, nativeEvent);
183 }
184
188 -export function dispatchEvent(
189 - topLevelType: DOMTopLevelEventType,
190 - nativeEvent: AnyNativeEvent,
191 -) {
185 +export function dispatchEvent(nativeEvent: AnyNativeEvent) {
186 if (!_enabled) {
187 return;
188 }
@@ -207,11 +201,7 @@ export function dispatchEvent(
201 targetInst = null;
202 }
203
210 - const bookKeeping = getTopLevelCallbackBookKeeping(
211 - topLevelType,
212 - nativeEvent,
213 - targetInst,
214 - );
204 + const bookKeeping = getTopLevelCallbackBookKeeping(nativeEvent, targetInst);
205
206 try {
207 // Event queue being processed in the same cycle allows
packages/react-dom/src/test-utils/ReactTestUtils.js
+4 -2
@@ -42,7 +42,9 @@ const [
42 runEventsInBatch,
43 ] = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
44
45 -function Event(suffix) {}
45 +function Event(type) {
46 + this.type = type;
47 +}
48
49 let hasWarnedAboutDeprecatedMockComponent = false;
50
@@ -59,7 +61,7 @@ let hasWarnedAboutDeprecatedMockComponent = false;
61 */
62 function simulateNativeEventOnNode(topLevelType, node, fakeNativeEvent) {
63 fakeNativeEvent.target = node;
62 - dispatchEvent(topLevelType, fakeNativeEvent);
64 + dispatchEvent(fakeNativeEvent);
65 }
66
67 /**