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
Use initialRouteName props (The name of the route to render on first load of the navigator) if you want a specific screen, otherwise the first stack screen will be rendered by default.
Stack navigators nested inside each screen of drawer navigator - The drawer appears over the header from the stack. Stack navigators nested inside each screen of tab navigator - The tab bar is always visible. Usually pressing the tab again also pops the stack to top.
StackNavigator: When user taps a link, a new screen is put on top of old screens. TabNavigator: User navigates to different screens by tapping on tabs along the top or bottom of the screen.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With