question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Integration issues with react-native-gesture-handler on Android

See original GitHub issue

I am attempting to use Navigation React Native as the routing solution for my native app and am liking it quite a bit: performant, simple, intuitive and quite flexible. However, In my early integration attempts (using some of the other core libraries i would be using in my redux-driven app) i find that I have a couple of Android-specific issues when i attempt integration with react-native-gesture-handler .

Main Issue

The SideDrawer seems to work only in the initial screen when an attempt is made to trigger it via a gesture (swipe left/right from the edges, depending on the configuration). When i navigate away to another screen that also has the SideDrawer, it does not work. It does work everywhere when i try to programmatically open/close, regardless of which screen i am on, however.

Secondary Issue

Additionally a minor issue was noticed as well. Running back actions, both via an app button and via the hardware back button, seem to flash the side drawer for about a second before navigation. It seems like it is navigating 2 steps instead of 1 with the flashing drawer seeming to visually appear as an intermediary screen.

Note: Everything works perfectly fine in IoS however.

I use the SideDrawer as an HOC, wrapping screens that would require the SideDrawer but have attempted using it normally as well.

The installation docs for react-native-gesture-handler has a section dedicated to installation for android apps that use native navigation libraries. Essentially they require wrapping each screen with a dedicated HOC shipped with the library.

As far i understand Navigation has a single ReactRoot(a recent change) and so, if wrapping is necessary, it can be done at the topmost level. I tried that but It didn’t work. I also attempted wrapping individual screens but with no success. Ive used the gesture handler library in other apps, both JS-driven(react-navigation, no change was necessary) and native (react-native-navigation, with integration of the specific changes required as was documented) and they work fine. My guess is i might perhaps be needing the wrapping of the dedicated HOC shipped with react-native-gesture-handler since, as per the installation docs for Navigation on React Native, there is specific mention of the use of native APIs for navigation:

The Navigation router for React Native uses the underlying native APIs to provide faithful navigation on Android and iOS.

My current minimal package.json:

{
  "name": "menuappnative",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "@react-native-community/async-storage": "^1.5.1",
    "@react-native-community/netinfo": "^4.0.0",
    "navigation": "^5.2.0",
    "navigation-react": "^4.1.1",
    "navigation-react-native": "^5.3.0",
    "prop-types": "^15.7.2",
    "react": "16.8.3",
    "react-native": "0.59.10",
    "react-native-device-info": "^2.2.2",
    "react-native-firebase": "^5.5.5",
    "react-native-gesture-handler": "^1.3.0",
    "react-native-vector-icons": "^6.6.0",
    "react-redux": "^7.1.0",
    "redux": "^4.0.3",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.5.4",
    "@babel/runtime": "^7.5.4",
    "babel-jest": "^24.8.0",
    "jest": "^24.8.0",
    "metro-react-native-babel-preset": "^0.55.0",
    "react-test-renderer": "16.8.3"
  },
  "jest": {
    "preset": "react-native"
  }
}

The App.js:

import React from 'react';
import { StateNavigator } from 'navigation';
import { NavigationHandler } from 'navigation-react';
import { NavigationStack } from 'navigation-react-native';
import { Alert, BackHandler } from 'react-native';
import { Provider } from 'react-redux';
import Menu from './Menu';
import store from './src/redux/store';
import Welcome from './Welcome';

const stateNavigator = new StateNavigator([
  {key: 'welcome', trackCrumbTrail: true},
  {key: 'menu', trackCrumbTrail: true},
]);

const {welcome,menu} = stateNavigator.states;
welcome.renderScene = () => <Welcome />;
menu.renderScene = () => <Menu />;
stateNavigator.navigate('welcome');

class App extends React.Component{
  componentDidMount(){
    BackHandler.addEventListener("hardwareBackPress",this._handleHardwareBackPress)
  }
  componentWillUnmount(){
    BackHandler.removeEventListener("hardwareBackPress",this._handleHardwareBackPress)
  }
  _handleHardwareBackPress=(args)=>{
      if(!stateNavigator.canNavigateBack(1)){
        Alert.alert("Show a prompt with OK/CANCEL")
        return true
      }
  }
  render(){
    return(
      <Provider store={store}>
          <NavigationHandler stateNavigator={stateNavigator}>
            <NavigationStack />
          </NavigationHandler>
      </Provider>
    );
  }
}
export default App;

The Welcome screen:

import React, { Component } from 'react';
import { NavigationContext } from 'navigation-react';
import { Button, SafeAreaView, StyleSheet, Text } from 'react-native';
import { connect } from 'react-redux';
//import SideDrawer from './src/modules/SideDrawer/SideDrawer';
import withSideDrawer from './src/helpers/hoc/withSideDrawer';

class Welcome extends Component {
  _onPress = (stateNavigator) => {
    stateNavigator.navigate('menu');
  }
  render() {
    return (
      <NavigationContext.Consumer>
        {({stateNavigator}) => (
          <SafeAreaView style={styles.container}>
            <Text>
              Welcome
            </Text>
              <Button title="To Menu Screen" onPress={() => this._onPress(stateNavigator)}/>
          </SafeAreaView>
        )}
      </NavigationContext.Consumer>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#E91E63'
  },
});

const mapStateToProps = (state) => {
  return {common: state.commonReducer, 
    nav: state.navigationReducer}
}
export default connect(mapStateToProps)(withSideDrawer(Welcome));

The Menu Screen

import { NavigationContext } from 'navigation-react';
import React, { Component } from 'react';
import { Button, SafeAreaView, StyleSheet, Text } from 'react-native';
import { connect } from 'react-redux';
import withSideDrawer from './src/helpers/hoc/withSideDrawer';

class Menu extends Component {
  _onPress = (stateNavigator) => {
    stateNavigator.navigateBack(1);
  }
  render() {
    return (
      <NavigationContext.Consumer>
        {({stateNavigator}) => (
          <SafeAreaView style={styles.container}>
            <Text>
              Menu
            </Text>
              <Button title="Back" onPress={() => this._onPress(stateNavigator)}/>
          </SafeAreaView>
        )}
      </NavigationContext.Consumer>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#E91E63'
  },
});

const mapStateToProps = (state) => {
  return {common: state.commonReducer, nav: state.navigationReducer}
}
export default connect(mapStateToProps)(withSideDrawer(Menu));

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:35 (35 by maintainers)

github_iconTop GitHub Comments

1reaction
grahammendickcommented, Sep 12, 2021

Routing in Next.js is an underwhelming implementation of a nice idea. I wrote about how they can get rid of nested files and still keep their file-based approach

1reaction
arunmenon1975commented, Sep 9, 2021

This is great news and perfect timing as well for me. My current project is scoped rather large at the moment: a PWA solution (with navigation-react powering the routing) as well as native Android/Ios apps. I went a monorepo route for all the benefits it affords and found that the navigation suite of packages is the only routing solution out there that could handle routing requirements across the device landscape (thus my projects landscape) via the same monorepo philosophy of shared packages and cohesive residency while following a uniform approach all through. Less stress/fatigue and better productivity when a suite of products follow a common methodology.

Due to some project requirement changes - as recent as the last couple of days - i had to basically go back to using Nextjs for my PWA which meant that i had to drop navigation-react. Its a trade-off with a lot of factors weighing in and the decision came after considerable thought.

However, navigation-react-native is the decided solution for my mobile apps. in fact i had already installed it in my monorepo even before starting out on the react-native project 😃 I like its unique approach and the fact that the navigation is native makes it a perfect optimal routing solution. Leaving aside the easy routing and now the drawer improvements, i would have chosen navigation-react-native just for its tabs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Troubleshooting | React Native Gesture Handler - Open Source
Changing enabled prop during a gesture has no effect, only when a gesture starts (that is a finger touches the screen) the enabled...
Read more >
Swipe Gestures not Working in Android - About React
Swipe Gestures not Working in Android- React Native Gesture Handler · 1 Problem Statement · 2 1. Solution for React Navigation V4. 2.1...
Read more >
react native gesture handler is not working with modal in ...
I am having an issue in using PanGestureHandler ...
Read more >
Troubleshooting | React Native Bottom Sheet - GitHub Pages
Pressables / Touchables are not working on Android​ ... Due to wrapping the content and handle with TapGestureHandler & PanGestureHandler , any gesture...
Read more >
Accessibility - React Native
Both Android and iOS provide APIs for integrating apps with assistive technologies like the bundled screen readers VoiceOver (iOS) and ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found