Search code examples
react-nativereact-navigationreact-navigation-v5react-navigation-bottom-tab

What is the proper way of dealing with navigation to screens located in separate navigators directly in react navigator 5?


I have aan app scenario where I have a Bottom tabs navigator as my base navigator tab with Home, Products ... as my tabs:

<Tab.Navigator
    screenOptions={{
      headerShown: true,
    }}
    tabBarOptions={{
      showLabel: false,
      activeTintColor: MyColors.COLOR_ACCENT,
    }}>
    <Tab.Screen
      name="Home"
      component={HomeStack}
      options={{
        tabBarIcon: ({color, size}) => (
          <Icon name="home" color={color} size={size} />
        ),
      }}
    />

    <Tab.Screen
      name="Product"
      component={ProductStack}
      options={{
        tabBarIcon: ({color, size}) => (
          <Icon name="business-center" color={color} size={size} />
        ),
      }}
    />
    <Tab.Screen
      name="Request"
      component={MedRequest}
      options={{
        color: MyColors.COLOR_PRIMARY,
        tabBarIcon: ({color, size}) => (
          <Icon
            name="near-me"
            color={color}
            size={35}
            style={{transform: [{rotateZ: '20deg'}]}}
          />
        ),
      }}
    />
    <Tab.Screen
      name="Reminder"
      component={Reminder}
      options={{
        tabBarIcon: ({color, size}) => (
          <Icon name="alarm" color={color} size={size} />
        ),
      }}
    />
    <Tab.Screen
      name="Location"
      component={LocationStack}
      options={{
        tabBarIcon: ({color, size}) => (
          <Icon name="location-on" color={color} size={size} />
        ),
      }}
    />
  </Tab.Navigator>

Lets consider my first 2 screens from Bottom Tabs. The first one is Home. It contains a list of top 5 popular products and a "view all" link which navigates it to the second tab products.

Each individual listed products are supposed to navigate to the product detail page.Since, the productDetail navigation is not defined in the bottom tabs navigator, I tried to resolve this by creating a new Stack navigator in home via homeStack which is as:

<Stack.Navigator
    screenOptions={{
      headerShown: false,
    }}>
    <Stack.Screen name="Home" component={Home} />
    <Stack.Screen name="Notifications" component={Notifications} />
    <Stack.Screen name="ProductDetail" component={ProductDetail} />
    <Stack.Screen name="AuthStack" component={AuthStack} />
    <Stack.Screen name="BlogStack" component={BlogStack} />
    <Stack.Screen name="BlogDetail" component={BlogDetail} />
    <Stack.Screen name="Cart" component={CartStack} />
  </Stack.Navigator>

Now that we have the productDetail navigator in handler, I am able to navigate to product detail. Similarly, the product bottom tab has another stack navigator as ProductStack on top which helps in navigation to its various links. It is as:

<Stack.Navigator
    screenOptions={{
      headerShown: false,
    }}>
    <Stack.Screen name="Product" component={Product} />
    <Stack.Screen name="CartStack" component={CartStack} />
    <Stack.Screen name="ProductDetail" component={ProductDetail} />
  </Stack.Navigator>

My main concern here is that I have been including the ProductDetail and CartStack as an element of navigators in more than one places and I have a feeling that I'm not doing this right.

Also can this multilevel stacking of navigators lead to a performance issue?

Also the cartStack I access when directly navigating to productDetail from home screen causes the disappearance of the bottom tabs.

Am I handling the situation totally wrong here?? Is there an easier way of doing this, that hasn't crossed my mind?


Solution

  • So it depends on which tab you want to stay on, if you want to stay on the home tab you can leave it in the home stack. If you want to go to the products tab -> product details page so when they go back/dismiss it will go back to the root screen of the products tab then you can do something like this to navigate to nested screens:

    navigation.navigate('Product', { screen: 'ProductDetail' });