Reputation: 265
I have 3 tabs and each tab contains a set of stack navigators.
const HomeNavigator = createStackNavigator();
const HomeStackNavigator = ({navigation, route}) => {
return (
<HomeNavigator.Navigator>
<HomeNavigator.Screen
name="Home"
component={Home}
/>
<HomeNavigator.Screen
name="Profile"
component={Profile}
/>
<HomeNavigator.Screen
name="Settings"
component={Settings}
/>
</HomeNavigator.Navigator>
);
};
const StoreNavigator = createStackNavigator();
const StoreStackNavigator = ({navigation, route}) => {
return (
<StoreNavigator.Navigator>
<StoreNavigator.Screen
name="OurStore"
component={Store}
/>
</StoreNavigator.Navigator>
);
};
const CommunityNavigator = createStackNavigator();
const CommunityStackNavigator = ({navigation, route}) => {
return (
<CommunityNavigator.Navigator>
<CommunityNavigator.Screen
name="Community"
component={Community}
/>
<CommunityNavigator.Screen
name="CommunityReply"
component={CommunityReply}
options={communityReplyOptions}
/>
<CommunityNavigator.Screen
name="AskCommunity"
component={AskCommunity}
/>
</CommunityNavigator.Navigator>
);
};
Tab Navigator
const MainNavigator = createBottomTabNavigator();
const MainTabNavigator = () => {
return (
<MainNavigator.Navigator
screenOptions={tabScreenOptions}
tabBarOptions={tabBarOptions}>
<MainNavigator.Screen
name="HomeTab"
component={HomeStackNavigator}
options={{tabBarLabel: 'Home'}}
/>
<MainNavigator.Screen
name="StoreTab"
component={StoreStackNavigator}
options={{tabBarLabel: 'Store'}}
/>
<MainNavigator.Screen
name="CommunityTab"
component={CommunityStackNavigator}
options={{tabBarLabel: 'Community'}}
/>
</MainNavigator.Navigator>
);
};
I navigated to CommunityReply Screen which is inside CommunityTab tab from HomeTab by clicking a button using the below approach
props.navigation.navigate('CommunityTab', { screen: 'CommunityReply', params: {postId: postId}, });
It's working fine, when I again come back to CommunityTab it will always be in CommunityReply Screen. How to reset tab stacks when you come back to a CommunityTab tab
React Navigation Versions
"@react-navigation/bottom-tabs": "^5.8.0"
"@react-navigation/native": "^5.7.3"
"@react-navigation/stack": "^5.9.0"
Upvotes: 10
Views: 16528
Reputation: 752
For posterity, if you want to avoid the unmountOnBlur
, you can also use the tabPress
event (see docs).
The docs in the link above give a nice overview of the default tab press behavior and how to modify it. You can also check out this handy Expo Snack demo.
In particular, to navigate to the initial route on tab press:
function SomeScreen({ navigation }) {
useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', e => {
e.preventDefault();
navigation.navigate('initialRouteName');
});
return unsubscribe;
}, [ navigation ]);
}
Bear in mind, if SomeScreen
is inside another (nested) navigator, it will be necessary to access the navigation
prop from the parent navigator when adding the event listener (navigation.getParent().addListener()
).
Upvotes: 0
Reputation: 51
I made a more generic approach to Jeison Guimarães solution (react navigation 6). This approach resets any stack navigation within a tab when the tab index changes. This also makes sure the active stack is not reset when a popover is shown.
<Tab.Screen
name="My tab"
listeners={resetTabStacksOnBlur}
/>
/**
* Resets tabs with stackNavigators to the first route when navigation to another tab
*/
const resetTabStacksOnBlur = ({navigation}) => ({
blur: () => {
const state = navigation.getState();
state.routes.forEach((route, tabIndex) => {
if (state?.index !== tabIndex && route.state?.index > 0) {
navigation.dispatch(StackActions.popToTop());
}
});
},
});
Upvotes: 5
Reputation: 2239
There is a property called unmountOnBlur designed for this purpose.
https://reactnavigation.org/docs/bottom-tab-navigator#unmountonblur
Changes to make in Tab Navigator :
const MainNavigator = createBottomTabNavigator();
const MainTabNavigator = () => {
return (
<MainNavigator.Navigator
- screenOptions={tabScreenOptions}
+ screenOptions={{...tabScreenOptions, unmountOnBlur: true }}
tabBarOptions={tabBarOptions}>
<MainNavigator.Screen
name="HomeTab"
component={HomeStackNavigator}
options={{tabBarLabel: 'Home'}}
/>
<MainNavigator.Screen
name="StoreTab"
component={StoreStackNavigator}
options={{tabBarLabel: 'Store'}}
/>
<MainNavigator.Screen
name="CommunityTab"
component={CommunityStackNavigator}
options={{tabBarLabel: 'Community'}}
/>
</MainNavigator.Navigator>
);
};
Summary:
unmountOnBlur: true
will solve the problem mentioned.
Upvotes: 29
Reputation: 141
If you don't want the CommunityReply
screen to show when you navigate back to the CommunityTab
you need to add an initial
option within your navigate
function.
props.navigation.navigate(
'CommunityTab',
{
screen: 'CommunityReply',
initial: false,
params: { postId: postId },
}
);
Explained here in the docs
Upvotes: 8
Reputation: 51
If the solution above not working for you, try this solution, its work for me.
import { CommonActions } from '@react-navigation/native';
<Tab.Screen listeners={({navigation,route})=>({
blur:()=>{
navigation.dispatch(
CommonActions.reset({
index:4,
routes:[{name:'Profile'}]
})
)
},
})} name="Profile"/>
Upvotes: 1