Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 206
osama somy Avatar asked Apr 28 '20 19:04

osama somy


People also ask

How do I change the initial screen in stack navigator?

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.

Can we nest a stack navigator inside a tab navigator?

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.

What is the difference between stack navigator and Tab navigator?

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.


2 Answers

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.

like image 173
Abhishek Shakya Avatar answered Oct 25 '22 22:10

Abhishek Shakya


enter image description here

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

like image 31
0xA Avatar answered Oct 25 '22 20:10

0xA