Reputation: 305
I have a @react-navigation/bottom-tabs navigator when my app opens whose contents are like:
<Tab.Navigator
tabBarOptions={{
activeTintColor: '#77dd77',
inactiveTintColor: 'gray',
}}
tabBar={props => <MyTabBar {...props} />}
backBehavior={"history"}
>
<Tab.Screen
name="Home"
component={Home}
options={{ title: 'Home' }}
/>
<Tab.Screen
name="Orders"
component={Orders}
options={{ title: 'Orders' }}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{ title: 'Profile' }}
/>
</Tab.Navigator>
I have a BackHandler in my code that makes the app exit when back button is pressed from the home page. Everything is fine and I have checked that the backhandler gets called when back button is pressed.
But when I switch to any other tab and then return to the homepage and press back to exit the app, backhandler stops working and the app shows error "The action 'GO_BACK'was not handled by any navigator. Is there any screen to go back to?"
This is a development-only warning but in the signed version, the app doesn't show any error and doesn't even exit.
How can I address this 'GO_BACK' action?
Upvotes: 10
Views: 11243
Reputation: 1177
Simple and Clean solution using Custom hook.
I have created a custom hook to handle back press in all bottom tabs.
// back handler hook
import React from 'react';
import {useEffect} from 'react';
import {BackHandler} from 'react-native';
export const useBackButton = (props, handler) => {
useEffect(() => {
props.navigation.addListener('focus', () => {
BackHandler.addEventListener('hardwareBackPress', handler);
});
props.navigation.addListener('blur', () => {
BackHandler.removeEventListener('hardwareBackPress', handler);
});
}, [handler]);
};
Now In home screen I added this
const onBackPress = () => {
BackHandler.exitApp();
return true;
};
useBackButton(props, onBackPress);
And In other screens I added following.
const onBackPress = () => {
props.navigation.goBack();
return true;
};
useBackButton(props, onBackPress);
Upvotes: 1
Reputation: 654
I was facing a similar issue, just found out the solution.
The problem was that I was trying to handle backHandler from the screen itself, but it just doesn't work like that with tab navigator (and maybe with react-navigation as a whole? I dunno).
Any way, you just need to add a listener for 'focus' (~componentDidMount) and 'blur' (~componentWillUnmount) like this:
<Tab.Screen name="Home" component={HomeScreen}
listeners={{ focus: () => BackHandler.addEventListener('hardwareBackPress',handleBackButton)
,blur: () => BackHandler.removeEventListener('hardwareBackPress',handleBackButton)
}}
/>
Where:
function handleBackButton () {
BackHandler.exitApp();
return true;
}
Now the backHandler function works in this way only in HomeScreen, and as usual in other screens.
Upvotes: 9
Reputation: 81
React Navigation (version 5) has already handled the native back button on bottom tabs.
I was stuck with this issue for one day and tried so many ways.
I ended up finding out in react-navigation version_5 that they have included it with just one line. https://reactnavigation.org/docs/bottom-tab-navigator/#backbehavior
Add the prop backBehaviour = "initialRoute" to your <Tab.Navigator/> and that will handle all native back button on tabs
<Tab.Navigator backBehaviour = "initialRoute" >
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
Upvotes: 4
Reputation: 305
I was using backhandler in all my tabs to create a navigation flow I wanted. Turns out this was creating the issue. After removing the backhandlers from the rest tabs, the app runs smoothly now.
I am now trying to experiment more with backBehavior in tab navigator to try to get the flow I want.
Writing my problem here gave me a clearer view of my problem!
Upvotes: 1