Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TouchableOpacity remains disabled after attempted click and state change from TextInput #2730

Closed
nathan-ahn opened this issue Jan 25, 2024 · 3 comments · Fixed by #2738
Closed
Labels
Platform: Web Repro provided A reproduction with a snack or repo is provided

Comments

@nathan-ahn
Copy link

Description

On web, when controlling the disabled state of a GH TouchableOpacity using a TextInput component (specifically onChangeText), the button becomes stuck as disabled after attempting a click. This issue only occurs after trying to click on the TouchableOpacity while it's disabled, and only when updating state using TextInput's onChangeText (There's a chance it's affected by other events, but I haven't tested). TouchableOpacity works as intended when using another Pressable to change the disabled state.

When stuck as disabled, onPress doesn't fire and the opacity doesn't change. This behavior is inconsistent with RN's original TouchableOpacity which correctly re-enables the TouchableOpacity after a text change.

Steps to reproduce

  1. Attempt to click the disabled TouchableOpacity
  2. Edit the text input (to trigger onChangeText)
  3. Attempt to click the TouchableOpacity (which should be enabled)

Snack or a link to a repository

https://snack.expo.dev/@nathan_ahn/gesture-handler-textinput-disabled-bug

Gesture Handler version

2.14.1

React Native version

0.72.4

Platforms

Web

JavaScript runtime

None

Workflow

Expo managed workflow

Architecture

None

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

@github-actions github-actions bot added Platform: Web Repro provided A reproduction with a snack or repo is provided labels Jan 25, 2024
@m-bert
Copy link
Contributor

m-bert commented Feb 1, 2024

Hi @nahn20! I've found out what causes that problem. Could you take a look at #2738 and confirm that it solves this issue?

@nathan-ahn
Copy link
Author

Thank you so much for the quick and concise fix!

I can't seem to get react-native-gesture-handler working locally so I can't test for myself, but given the test plan it looks like it solves this issue!

@m-bert
Copy link
Contributor

m-bert commented Feb 5, 2024

In that case, I will merge it asap. I hope it will help, but if not - please get back to this issue!

m-bert added a commit that referenced this issue Feb 5, 2024
## Description

While investigating #2370 I've found out that if handler has `enabled: false` and moves to state `END`, it won't reach `UNDETERMINED`. This fact makes it useless because it is stuck at finished state. It happens because of [this line](https://github.com/software-mansion/react-native-gesture-handler/blob/a30f42f3fe5f08e9746864a7e6f7a15d15936a0f/src/web/tools/GestureHandlerOrchestrator.ts#L118). In order to fix that, I've decided to reset handler in case if it moves to `END` state while being inactive.

Fixes #2730

## Test plan

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

```jsx
import React, { useState } from 'react';
import {
  View,
  SafeAreaView,
  Text,
  TextInput,
  TouchableOpacity as RNTouchable,
} from 'react-native';
import { TouchableOpacity as GHTouchable } from 'react-native-gesture-handler';

const BrokenGestureHandlerTouchable = () => {
  const [disabled, setDisabled] = useState(true);
  const [didClick, setDidClick] = useState(false);
  return (
    <View>
      <Text>
        Breaks with react-native-gesture-handler's TouchableOpacity. Refresh the
        page, click the disabled button, edit the text, click the button that
        should be enabled again and the click isn't triggered (no opacity change
        and no function call). If you refresh the page, edit the text, then
        click the enabled button, it works as expected.
      </Text>
      <TextInput
        placeholder="Text Input"
        placeholderTextColor="#AAAAAA"
        onChangeText={(text) => {
          setDisabled(false);
        }}
      />
      <GHTouchable
        disabled={disabled}
        onPress={() => {
          setDidClick(true);
        }}
        style={{
          borderWidth: 1,
          borderColor: 'pink',
        }}>
        <Text>Click me! {`Disabled: ${disabled}. Clicked: ${didClick}`}</Text>
      </GHTouchable>
    </View>
  );
};

const WorkingReactNativeTouchable = () => {
  const [disabled, setDisabled] = useState(true);
  const [didClick, setDidClick] = useState(false);
  return (
    <View>
      <Text>
        Works with react-native's TouchableOpacity. Refresh the page, click the
        disabled button, edit the text, click the now-enabled button again and
        it works.
      </Text>
      <TextInput
        placeholder="Text Input"
        placeholderTextColor="#AAAAAA"
        onChangeText={(text) => {
          setDisabled(false);
        }}
      />
      <RNTouchable
        disabled={disabled}
        onPress={() => {
          setDidClick(true);
        }}
        style={{
          borderWidth: 1,
          borderColor: 'pink',
        }}>
        <Text>Click me! {`Disabled: ${disabled}. Clicked: ${didClick}`}</Text>
      </RNTouchable>
    </View>
  );
};

export default function App() {
  return (
    <SafeAreaView>
      <WorkingReactNativeTouchable />
      <View
        style={{
          height: 50,
        }}
      />
      <BrokenGestureHandlerTouchable />
    </SafeAreaView>
  );
}

```

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Web Repro provided A reproduction with a snack or repo is provided
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants