From e86146e714bb98e973404350069915bf2760a1bd Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 5 Sep 2019 00:36:29 +0100 Subject: [PATCH] [react-events] Refine executeUserEventHandler (#16662) --- packages/legacy-events/ReactGenericBatching.js | 7 +++++-- .../react-dom/src/events/DOMEventResponderSystem.js | 13 ++++++++----- packages/react-events/src/dom/Keyboard.js | 10 +++++----- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/legacy-events/ReactGenericBatching.js b/packages/legacy-events/ReactGenericBatching.js index 3d1acebde6126..81441775a33cb 100644 --- a/packages/legacy-events/ReactGenericBatching.js +++ b/packages/legacy-events/ReactGenericBatching.js @@ -9,7 +9,9 @@ import { needsStateRestore, restoreStateIfNeeded, } from './ReactControlledComponent'; + import {enableFlareAPI} from 'shared/ReactFeatureFlags'; +import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils'; // Used as a way to call batchedUpdates when we don't have a reference to // the renderer. Such as when we're dispatching events or if third party @@ -76,11 +78,12 @@ export function batchedEventUpdates(fn, a, b) { } // This is for the React Flare event system -export function executeUserEventHandler(fn: any => void, value: any): any { +export function executeUserEventHandler(fn: any => void, value: any): void { const previouslyInEventHandler = isInsideEventHandler; try { isInsideEventHandler = true; - return fn(value); + const type = typeof value === 'object' && value !== null ? value.type : ''; + invokeGuardedCallbackAndCatchFirstError(type, fn, undefined, value); } finally { isInsideEventHandler = previouslyInEventHandler; } diff --git a/packages/react-dom/src/events/DOMEventResponderSystem.js b/packages/react-dom/src/events/DOMEventResponderSystem.js index 8d08029344325..77adac19036ae 100644 --- a/packages/react-dom/src/events/DOMEventResponderSystem.js +++ b/packages/react-dom/src/events/DOMEventResponderSystem.js @@ -92,27 +92,30 @@ const eventResponderContext: ReactDOMResponderContext = { eventValue: any, eventListener: any => void, eventPriority: EventPriority, - ): any { + ): void { validateResponderContext(); validateEventValue(eventValue); switch (eventPriority) { case DiscreteEvent: { flushDiscreteUpdatesIfNeeded(currentTimeStamp); - return discreteUpdates(() => + discreteUpdates(() => executeUserEventHandler(eventListener, eventValue), ); + break; } case UserBlockingEvent: { if (enableUserBlockingEvents) { - return runWithPriority(UserBlockingPriority, () => + runWithPriority(UserBlockingPriority, () => executeUserEventHandler(eventListener, eventValue), ); } else { - return executeUserEventHandler(eventListener, eventValue); + executeUserEventHandler(eventListener, eventValue); } + break; } case ContinuousEvent: { - return executeUserEventHandler(eventListener, eventValue); + executeUserEventHandler(eventListener, eventValue); + break; } } }, diff --git a/packages/react-events/src/dom/Keyboard.js b/packages/react-events/src/dom/Keyboard.js index 76a76a3a86e38..133ce4608a787 100644 --- a/packages/react-events/src/dom/Keyboard.js +++ b/packages/react-events/src/dom/Keyboard.js @@ -173,11 +173,11 @@ function dispatchKeyboardEvent( type, defaultPrevented, ); - const shouldPropagate = context.dispatchEvent( - syntheticEvent, - listener, - DiscreteEvent, - ); + let shouldPropagate; + const listenerWithReturnValue = e => { + shouldPropagate = listener(e); + }; + context.dispatchEvent(syntheticEvent, listenerWithReturnValue, DiscreteEvent); if (shouldPropagate) { context.continuePropagation(); }