-
-
Notifications
You must be signed in to change notification settings - Fork 981
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
GestureDetector is not responsive #2920
Comments
Hey! 👋 The issue doesn't seem to contain a minimal reproduction. Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem? |
I've attached the link - https://github.com/Expensify/App. |
I spent some time looking into this and I managed to track it down to be caused by This is enough to reproduce the issue: import {useState} from 'react';
import {Freeze} from 'react-freeze';
import {View, Button, SafeAreaView} from 'react-native';
import {
Gesture,
GestureDetector,
GestureHandlerRootView,
} from 'react-native-gesture-handler';
export default function FirstScreen() {
const [frozen, setFrozen] = useState(false);
const tap = Gesture.Tap().onStart(() => {
console.log('Tap');
});
return (
<GestureHandlerRootView style={{flex: 1}}>
<SafeAreaView style={{flex: 1, backgroundColor: 'red'}}>
<Button title="Unfreeze" onPress={() => setFrozen(false)} />
<Freeze freeze={frozen}>
<View>
<GestureDetector gesture={tap}>
<View
style={{width: 100, height: 100, backgroundColor: 'blue'}}
/>
</GestureDetector>
<View style={{width: 100, height: 100, backgroundColor: 'green'}} />
<Button title="Freeze" onPress={() => setFrozen(true)} />
</View>
</Freeze>
</SafeAreaView>
</GestureHandlerRootView>
);
} It's only reproducible on iOS, because Android keeps hidden views mounted (at the moment of writing): https://github.com/facebook/react-native/blob/9dfcb9ec3ae6987a3231e4d6dd2bf8fb557440c8/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp#L217-L223 I will come back to it next week, after App.js conf. |
…#2925) ## Description Fixes #2920 When the subtree containing `GestureDetector` was suspended, all the native views were unmounted without the `Detector` component being aware. As a consequence, the view with the attached native recognizer was put in the recycling pool and then reused in other places in the UI (which is bad). Then, when the tree was unsuspended, the gesture didn't work correctly - again, `Detector` wasn't aware of any change, and a different native view was put as its child so the native recognizer wasn't attached to it. This PR changes the effect responsible for the initial setup and cleanup to be a layout effect, which gets triggered when the tree is suspended. This means that when tree suspends, native recognizers will be dropped and recreated when the tree unsuspends. Note that this will only fix the issue on RN 0.74, since `useLayoutEffect` is broken on versions below that. ## Test plan <details> <summary>Tested on the example app and the following code</summary> ```jsx import {useState} from 'react'; import {Freeze} from 'react-freeze'; import {View, Button, SafeAreaView} from 'react-native'; import { Gesture, GestureDetector, GestureHandlerRootView, } from 'react-native-gesture-handler'; export default function FirstScreen() { const [frozen, setFrozen] = useState(false); const tap = Gesture.Tap().onStart(() => { console.log('Tap'); }); return ( <GestureHandlerRootView style={{flex: 1}}> <SafeAreaView style={{flex: 1, backgroundColor: 'red'}}> <Button title="Unfreeze" onPress={() => setFrozen(false)} /> <Freeze freeze={frozen}> <View> <GestureDetector gesture={tap}> <View style={{width: 100, height: 100, backgroundColor: 'blue'}} /> </GestureDetector> <View style={{width: 100, height: 100, backgroundColor: 'green'}} /> <Button title="Freeze" onPress={() => setFrozen(true)} /> </View> </Freeze> </SafeAreaView> </GestureHandlerRootView> ); } ``` </details>
Thank you guys! I am going to test it as well 🙂 |
Btw, when can we expect the next release? |
Next week at the earliest. |
Description
The app uses GestureDetector to handle a tap on the send button. GestureDetector works properly when the user opens a chat screen. However, if the user opens nested chats (threads), returns to the 1st one, and taps on the send button, GestureDetector does not react to this action. The expected behavior is to have the button responsive.
Note: the bug is replicated for a case when there are 2 nested screens e.g. Main chat -> Subchat -> Subchat.
There is an issue with the Expensify app - Expensify/App#41528.
Video
Bug6469224_1714674407897.RPReplay_Final1714674254.mp4
Looks like at some moment GestureDetector loses a "connection" for the initial screen send button.
I've tried to do a force update for GestureDetector via setting and updating a
key
when the screen is focused, and it helps. So it requires a rerender of GestureDetector to refresh the "connection" and handle tap events.Details
Steps to reproduce
Snack or a link to a repository
https://github.com/Expensify/App
Gesture Handler version
2.14.1
React Native version
0.73.4
Platforms
iOS
JavaScript runtime
Hermes
Workflow
React Native (without Expo)
Architecture
Fabric (New Architecture)
Build type
Debug mode
Device
iOS simulator
Device model
iPhone 15 Pro Max (IOS 17.5)
Acknowledgements
Yes
The text was updated successfully, but these errors were encountered: