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 {