Skip to content

Commit

Permalink
[Web] Register/unregister listeners when enabled changes (#3330)
Browse files Browse the repository at this point in the history
## 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

<details>
<summary>Tested on the following code:</summary>

```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 (
    <View style={styles.container}>
      <GestureDetector gesture={gesture}>
        <View style={styles.circle} />
      </GestureDetector>

      <Pressable
        onPress={() => setEnabled((prev) => !prev)}
        style={styles.button}
      />
    </View>
  );
}

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',
  },
});
```

</details>

With small modification in `PanGestureHandler`:

```diff
+  protected init(viewRef: number, propsRef: React.RefObject<unknown>): void {
+    super.init(viewRef, propsRef);
+    setInterval(() => {
+      console.log(this.currentState);
+    }, 100);
+  }
```
  • Loading branch information
m-bert authored Jan 15, 2025
1 parent 3e88432 commit 9cef24e
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/web/tools/GestureHandlerWebDelegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 9cef24e

Please sign in to comment.