software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
5.85k stars 954 forks source link

Expo app crashes when using GestureDetector #2846

Closed Ever-It-Lazy closed 1 month ago

Ever-It-Lazy commented 1 month ago

Description

I am coding an Expo app that uses @react-navigation/native-stack for navigation and react-native-gesture-handler to track gesture on one screen. It loads fine, but completing the Gesture.Tap() (which should navigate to another screen) crashes Expo.

(This issue bares a vague resemblance to 2840, but I've investigated: they appear to be different.)

Steps to reproduce

I provide a repo as a simple example.

Snack or a link to a repository

https://github.com/Ever-It-Lazy/gesture_example

Gesture Handler version

2.14.0

React Native version

0.73.6

Platforms

iOS

JavaScript runtime

None

Workflow

Expo managed workflow

Architecture

None

Build type

None

Device

iOS simulator

Device model

iPhone X (iOS 16.7.7)

Acknowledgements

Yes

m-bert commented 1 month ago

Hi @Ever-It-Lazy! Thanks to expo team I was able to identify what causes this problem. The error here was missing runOnJS. Gesture callbacks are automatically workletized, but navigation runs on JS thread - therefore you were trying to call non-worklet function on the UI thread.

I've also made some adjustments in your code:

App.js

<Stack.Screen name="GestureScreen" component={GestureScreen} />

You don't have to use gestureHandlerRootHOC if you already have GestureHandlerRootView on the GestureScreen

GestureScreen.js

export default function StartScreen({ navigation }) {
  const doubleTap = Gesture.Tap()
    .numberOfTaps(2)
    .onEnd(() => {
      navigation.navigate("OtherScreen");
    })
    .runOnJS(true);

  return (
    <GestureHandlerRootView style={styles.container}>
      <GestureDetector gesture={doubleTap}>
        <View style={styles.button}>
          <Text style={styles.buttonLabel}>
            Double Tap to go to the other screen
          </Text>
        </View>
      </GestureDetector>
    </GestureHandlerRootView>
  );
}

Here I've changed few things:

So overall, to get rid of this problem you have to add runOnJS(true) to the gesture builder. Let me know if it helps!

Ever-It-Lazy commented 1 month ago

That solved it. Thanks for the other best practices suggestions, as well!

Under-Warz commented 1 week ago

Hi, I'm facing the same issue with my app (RN 0.73.6, RNGH 2.16, Reanimated 3.10 & Expo 50, Fabric ON)

I made a sample project using same stack (without Expo) to reproduce the issue with a simple case and the app crash on view using the GestureDetector even if I add .runOnJS(true).

Here is the sample app => https://github.com/Under-Warz/rngh_sample/blob/main

If anyone have an idea ?

PS : I can't update our app to RN 0.74 because of Expo 50 which is not supported on 0.74 and we have to wait for Expo 51

m-bert commented 6 days ago

Hi @Under-Warz! I've just run your sample app on both, Android emulator and iOS simulator - both work fine. Moreover, there's no need to add runOnJS in that case. Could you show some error logs?

Under-Warz commented 1 day ago

thank's @m-bert for you test. Could you give me your version of xcode & ios you are using for the test ? I can't understand why it's crashing here...

The only log message from Xcode when the app crash is

Assertion failed: (hasNativeState<T>(runtime)), function getNativeState, file jsi-inl.h, line 220.
Message from debugger: Terminated due to signal 6
Under-Warz commented 20 hours ago

@m-bert just to be sure, did you install the pods with RCT_NEW_ARCH_ENABLED=1 because I didn't setup the Android to use new arch on the sample project.

m-bert commented 1 hour ago

did you install the pods with RCT_NEW_ARCH_ENABLED=1

I've checked that on old architecture, but I will look into it

Could you give me your version of xcode & ios you are using for the test ?

I've just got Xcode update to version 15.4 and iOS to 17.5, I'll check if it still works for me (also on new arch) and get back to you