Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Navigation weird back button behavior in nested navigators

I'm using React Navigation in my app and I have a Tab Navigator nested in a Stack Navigator. Sometimes in the app, the navigation stack is:

Screen A => Tab Navigator => Screen B.

So when users are in Screen B and press the back button it triggers first the back action in the Tab Navigator and only if there's no goBack action available in the Tab Navigator that it triggers the goBack action from Screen B.

So, the user gets an unexpected behavior when he is in Screen B and have navigated between Tabs. The user keeps pressing the back button until the Tab Navigator is back to the first tab and only then, after another press in the back button, it goes from Screen B back to the tabs.

Is there anyway I can archieve the expected behaviour in this case?

like image 504
Thiago Nascimento Avatar asked Dec 10 '18 00:12

Thiago Nascimento


People also ask

How do you handle the back button in React Native navigation?

By default React Navigation will handle the Android back button for you, however we'll need to override the defaults. If you're at the top of the stack and press the android back button the application will close. If you've navigated within the stack anywhere then the screen will pop.

Can we pass params in goBack react navigation?

Unfortunately, you can not pass data like this when using the goBack() method.

What is the difference between react navigation and React Native navigation?

TL;DR: React Navigation uses a combination of libraries to provide a near-native experience, while RNN utilizes native fragments for each screen. Performance is the first parameter when selecting a navigation library for your app. The number of frames displayed per second determines the smoothness of the interface.


2 Answers

If I understand your setup correctly, I think you want to set backBehavior: 'none' on the TabNavigatorConfig. This will prevent tab navigations from pushing history states.

For example:

const MyTabNav = createBottomTabNavigator({
  ScreenOne: ScreenOne,
  ...
}, {
  backBehavior: 'none', // <-- Here
  initialRouteName: 'ScreenOne',
  tabBarOptions: {
    ...
  }
})

If that doesn't do exactly what you want, you might try playing with the other back behaviors. Two new behaviors were just added in version 3.2.0 (see https://github.com/react-navigation/rfcs/blob/master/text/0008-back-behaviour-for-tabs.md).

like image 184
Tony Gentilcore Avatar answered Oct 13 '22 08:10

Tony Gentilcore


Are you correctly handling the back button? on each container top level component you need to handle the back button press, ex:

import * as React from 'react';
import { BackHandler } from 'react-native';

export default MyComponent extends React.Component<any, any> {
  public componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', this.goBack);
  }

  public componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', this.goBack);
  }

  private goBack = () => {
    this.props.navigation.goBack();
    return true;
  }
}

By returning true, you stop the cascading of the back button press propagation to the previous containers.

like image 29
Oscar Franco Avatar answered Oct 13 '22 09:10

Oscar Franco