From 9cef24ef5c5755375e2c5f3888a1fbf8709bd115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= <63123542+m-bert@users.noreply.github.com> Date: Wed, 15 Jan 2025 13:30:40 +0100 Subject: [PATCH] [Web] Register/unregister listeners when `enabled` changes (#3330) ## Description Currently `enabled` property on web may stop handler from sending events. The problem here is that it still acts as it would be enabled, even if `enabled` is set to `false`. This PR adds logic that unregisters event listeners when `enabled` property is changed to `false`. ## Test plan
Tested on the following code: ```jsx import React from 'react'; import { StyleSheet, View, Pressable } from 'react-native'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; export default function EmptyExample() { const [enabled, setEnabled] = React.useState(true); const gesture = Gesture.Pan().enabled(enabled); return ( setEnabled((prev) => !prev)} style={styles.button} /> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', gap: 20, }, circle: { width: 100, height: 100, borderRadius: 50, backgroundColor: 'red', }, button: { width: 100, height: 35, borderRadius: 10, backgroundColor: 'plum', }, }); ```
With small modification in `PanGestureHandler`: ```diff + protected init(viewRef: number, propsRef: React.RefObject): void { + super.init(viewRef, propsRef); + setInterval(() => { + console.log(this.currentState); + }, 100); + } ``` --- src/web/tools/GestureHandlerWebDelegate.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/web/tools/GestureHandlerWebDelegate.ts b/src/web/tools/GestureHandlerWebDelegate.ts index a21379d9a7..ec34089851 100644 --- a/src/web/tools/GestureHandlerWebDelegate.ts +++ b/src/web/tools/GestureHandlerWebDelegate.ts @@ -174,6 +174,21 @@ export class GestureHandlerWebDelegate this.setUserSelect(enabled); this.setTouchAction(enabled); this.setContextMenu(enabled); + + if (enabled) { + this.eventManagers.forEach((manager) => { + // It may look like managers will be registered twice when handler is mounted for the first time. + // However, `init` method is called AFTER `updateGestureConfig` - it means that delegate has not + // been initialized yet, so this code won't be executed. + // + // Also, because we use defined functions, not lambdas, they will not be registered multiple times. + manager.registerListeners(); + }); + } else { + this.eventManagers.forEach((manager) => { + manager.unregisterListeners(); + }); + } } onBegin(): void {