'How to set always first screen of Stack Navigator inside Tab Navigator React Navigation 5
React Navigation 5
I've build a StackNavigator inside of a TabNavigator, and the navigation between home screen and other screens is working. But the problem is,When I move from Tab2 to Tab1 I expect Tab1 always show me first screen of StackNavigator.
tab1
-> Stack
-screen1
-screen2
tab2
I am on screen2 and then move to tab2 after that then I move back to Tab1 I want to always display screen1.
I am try to use
OnTabPress({navigation})=>{
navigation.navigate("stackName",{
screen: "screen1"
}).
}
Its work but its show me screen2 first then navigate to screen1. Is there any other Solution. https://snack.expo.io/@usamasomy/groaning-donut
Solution 1:[1]
Use unmountOnBlur: true in options. Eg.
<Tab.Screen
name="Stack1"
component={Stack1}
options={{
tabBarLabel: "Stack1",
unmountOnBlur: true,
}}
/>
So when you are navigating away from this tab and you're on screen2 of Stack1, you will always come on the first screen of this stackNavigator when coming back to this tab.
Solution 2:[2]
initialRouteName= "NAME"
is the keyword to make sure you have a default
and make sure you use navigate()
push()
pop()
accordingly.
Firstly, create a custom TabBar so we can write our own functions executed by onPress
function MyTabBar({ state, descriptors, navigation }) {
return (
<View style={{ flexDirection: 'row' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
navigation.reset({
index: 0,
routes: [{ name: 'Screen1' }],
})
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
}}
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
Then in the TabScreens
override the original TabBar
in Tab.Navigator
by using tabBar=...
then call navigation.reset()
with index:0
and routes:{{name: 'Screen1'}}
every time MyTabBar
is pressed.
const TabScreens = ()=>{
return(
<Tab.Navigator tabBar={props => <MyTabBar {...props} />} initialRouteName="Tab1Screens" >
<Tab.Screen
name = "Tab1Screens"
component = {Tab1Screens}
/>
<Tab.Screen
name = "Tab2Screens"
component = {Tab2Screens}
/>
</Tab.Navigator>
)
}
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityStates={isFocused ? ['selected'] : []}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
{label}
</Text>
</TouchableOpacity>
);
})}
</View>
);
}
This can be greatly improved eg:
-some logic before `navigation.reset()`
-Accessing onPress without creating a new component
-etc..
finally snack available here :https://snack.expo.io/@karammarrie/customtabbar
Solution 3:[3]
i have a simple solution is to set initialRouteName= "screen1" in
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
initialRouteName="screen1"
>
<Stack.Screen name="screen1" component={Screen1} />
<Stack.Screen name="screen2" component={Screen2} />
</Stack.Navigator>
{/** **/}
if the screen still shows the first screen 2, you just need to comment the line <Stack.Screen name="screen2" component={Screen2} />
and reload the screen, then remove the comment line.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Abhishek Shakya |
Solution 2 | |
Solution 3 |