Reputation: 1155
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?
Upvotes: 18
Views: 4775
Reputation: 71
You can handle it using BackHandler event in TabNavigator page.
componentDidMount() {
if ("android" === Platform.OS) {
BackHandler.addEventListener("hardwareBackPress", this.handleBackPress);
}
}
componentWillUnmount() {
if ("android" === Platform.OS) {
BackHandler.removeEventListener(
"hardwareBackPress",
this.handleBackPress
);
}
}
handleBackPress = () => {
if (this.props.navigation.isFocused()) {
this.navigateBack();
} else {
this.props.navigation.goBack(null);
}
return true;
};
When hardware back button is pressed in screen B, backhandler method in Tab will get called and the flow will works properly.
But I have an issue in another scenario.
I have following work flow.
Tab Navigator A -> Tab Navigator B -> Screen
When back button is pressed from screen, the issue still persist.
Upvotes: 0
Reputation: 203
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).
Upvotes: 5
Reputation: 6228
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.
Upvotes: 1