Skip to content

Commit 38fa840

Browse files
authored
Experiemental event API - wrap async dispatched events (#15299)
1 parent 4d5cb64 commit 38fa840

File tree

3 files changed

+50
-39
lines changed

3 files changed

+50
-39
lines changed

packages/events/EventTypes.js

+1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ export type EventResponderContext = {
3939
) => void,
4040
requestOwnership: (target: Element | Document | null) => boolean,
4141
releaseOwnership: (target: Element | Document | null) => boolean,
42+
withAsyncDispatching: (func: () => void) => void,
4243
};

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

+15-14
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,13 @@ type EventQueue = {
5858
bubble: null | Array<$Shape<PartialEventObject>>,
5959
capture: null | Array<$Shape<PartialEventObject>>,
6060
discrete: boolean,
61-
phase: EventQueuePhase,
6261
};
63-
type EventQueuePhase = 0 | 1;
6462

65-
const DURING_EVENT_PHASE = 0;
66-
const AFTER_EVENT_PHASE = 1;
67-
68-
function createEventQueue(phase: EventQueuePhase): EventQueue {
63+
function createEventQueue(): EventQueue {
6964
return {
7065
bubble: null,
7166
capture: null,
7267
discrete: false,
73-
phase,
7468
};
7569
}
7670

@@ -134,7 +128,7 @@ function DOMEventResponderContext(
134128
this._discreteEvents = null;
135129
this._nonDiscreteEvents = null;
136130
this._isBatching = true;
137-
this._eventQueue = createEventQueue(DURING_EVENT_PHASE);
131+
this._eventQueue = createEventQueue();
138132
}
139133

140134
DOMEventResponderContext.prototype.isPassive = function(): boolean {
@@ -203,9 +197,6 @@ DOMEventResponderContext.prototype.dispatchEvent = function(
203197
if (stopPropagation) {
204198
eventsWithStopPropagation.add(eventObject);
205199
}
206-
if (eventQueue.phase === AFTER_EVENT_PHASE) {
207-
batchedUpdates(processEventQueue, eventQueue);
208-
}
209200
};
210201

211202
DOMEventResponderContext.prototype.isTargetWithinEventComponent = function(
@@ -320,6 +311,19 @@ DOMEventResponderContext.prototype.releaseOwnership = function(
320311
return false;
321312
};
322313

314+
DOMEventResponderContext.prototype.withAsyncDispatching = function(
315+
func: () => void,
316+
) {
317+
const previousEventQueue = this._eventQueue;
318+
this._eventQueue = createEventQueue();
319+
try {
320+
func();
321+
batchedUpdates(processEventQueue, this._eventQueue);
322+
} finally {
323+
this._eventQueue = previousEventQueue;
324+
}
325+
};
326+
323327
function getTargetEventTypes(
324328
eventTypes: Array<ReactEventResponderEventType>,
325329
): Set<DOMTopLevelEventType> {
@@ -401,8 +405,5 @@ export function runResponderEventsInBatch(
401405
}
402406
}
403407
processEventQueue(context._eventQueue);
404-
// In order to capture and process async events from responder modules
405-
// we create a new event queue.
406-
context._eventQueue = createEventQueue(AFTER_EVENT_PHASE);
407408
}
408409
}

packages/react-events/src/Press.js

+34-25
Original file line numberDiff line numberDiff line change
@@ -118,33 +118,42 @@ function dispatchPressStartEvents(
118118
DEFAULT_LONG_PRESS_DELAY_MS,
119119
);
120120

121-
state.longPressTimeout = setTimeout(() => {
122-
state.isLongPressed = true;
123-
state.longPressTimeout = null;
121+
state.longPressTimeout = setTimeout(
122+
() =>
123+
context.withAsyncDispatching(() => {
124+
state.isLongPressed = true;
125+
state.longPressTimeout = null;
124126

125-
if (props.onLongPress) {
126-
const longPressEventListener = e => {
127-
props.onLongPress(e);
128-
// TODO address this again at some point
129-
// if (e.nativeEvent.defaultPrevented) {
130-
// state.defaultPrevented = true;
131-
// }
132-
};
133-
dispatchPressEvent(context, state, 'longpress', longPressEventListener);
134-
}
127+
if (props.onLongPress) {
128+
const longPressEventListener = e => {
129+
props.onLongPress(e);
130+
// TODO address this again at some point
131+
// if (e.nativeEvent.defaultPrevented) {
132+
// state.defaultPrevented = true;
133+
// }
134+
};
135+
dispatchPressEvent(
136+
context,
137+
state,
138+
'longpress',
139+
longPressEventListener,
140+
);
141+
}
135142

136-
if (props.onLongPressChange) {
137-
const longPressChangeEventListener = () => {
138-
props.onLongPressChange(true);
139-
};
140-
dispatchPressEvent(
141-
context,
142-
state,
143-
'longpresschange',
144-
longPressChangeEventListener,
145-
);
146-
}
147-
}, delayLongPress);
143+
if (props.onLongPressChange) {
144+
const longPressChangeEventListener = () => {
145+
props.onLongPressChange(true);
146+
};
147+
dispatchPressEvent(
148+
context,
149+
state,
150+
'longpresschange',
151+
longPressChangeEventListener,
152+
);
153+
}
154+
}),
155+
delayLongPress,
156+
);
148157
}
149158
}
150159

0 commit comments

Comments
 (0)