From 893963a79932a4faa79432690858f3504e3c2ba1 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sun, 18 Feb 2018 16:10:44 -0800 Subject: [PATCH] [fix] PanResponder grant firing twice on touch devices Touch events can produce trailing mouse events, which cause unwanted events to fire in the responder event system. This issue is avoided in `Touchable` by cancelling the event in the responder release callback. To fix the issue in other areas, like the PaneResponder, this hack is moved into `createElement` and applied to event `onResponderRelease` callback. Fix #802 --- .../react-native-web/src/exports/Touchable/index.js | 7 ------- .../src/exports/createElement/index.js | 11 +++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/react-native-web/src/exports/Touchable/index.js b/packages/react-native-web/src/exports/Touchable/index.js index 82a12258..e188f9bf 100644 --- a/packages/react-native-web/src/exports/Touchable/index.js +++ b/packages/react-native-web/src/exports/Touchable/index.js @@ -424,13 +424,6 @@ const TouchableMixin = { */ touchableHandleResponderRelease: function(e: Event) { this._receiveSignal(Signals.RESPONDER_RELEASE, e); - // Browsers fire mouse events after touch events. This causes the - // 'onResponderRelease' handler to be called twice for Touchables. - // Auto-fix this issue by calling 'preventDefault' to cancel the mouse - // events. - if (e.cancelable && !e.isDefaultPrevented()) { - e.preventDefault(); - } }, /** diff --git a/packages/react-native-web/src/exports/createElement/index.js b/packages/react-native-web/src/exports/createElement/index.js index f726eff6..37d325b0 100644 --- a/packages/react-native-web/src/exports/createElement/index.js +++ b/packages/react-native-web/src/exports/createElement/index.js @@ -52,6 +52,17 @@ const adjustProps = domProps => { if (isEventHandler) { if (isButtonRole && isDisabled) { domProps[propName] = undefined; + } else if (propName === 'onResponderRelease') { + // Browsers fire mouse events after touch events. This causes the + // 'onResponderRelease' handler to be called twice for Touchables. + // Auto-fix this issue by calling 'preventDefault' to cancel the mouse + // events. + domProps[propName] = e => { + if (e.cancelable && !e.isDefaultPrevented()) { + e.preventDefault(); + } + return prop(e); + }; } else { // TODO: move this out of the render path domProps[propName] = e => {