1

I am building an app using react-native 0.64 and react-navigation v5.

I am trying to achieve a navigation structure with a Drawer on top, a HomeScreen (WITHOUT bottom tabs) with buttons to navigate to 5 screens -those WITH bottom tabs- and a BottomTab with 6 tabs: same 5 screens (each of them allows to navigate to a different sub-screen) and a tab for the HomeScreen.

According to react-navigation docs (Hiding tab bar in specific screens), in my implementation I avoid to use 'tabBarVisible' prop and instead I put HomeScreen in a parent Stack while the BottomTab is one of its screens. The problem is I would like to have in the BottomTab a tab for HomeScreen even if this screen is not inside the BottomTab (when the user press on the Home tab the app should navigate to the HomeScreen where the BottomTab won't be present anymore).

What I tried to implement is a structure like this:

  • [Drawer]
    • [MainStack]
      • HomeScreen
      • [BottomTab]
        • HomeScreen (with listener prop that on 'tabPress' => navigates back to HomeScreen)
        • [Stack1]
          • Screen1
          • DetailScreen1
        • [Stack2]
          • Screen2
          • DetailScreen2
        • . . . (other 3 stacks)

QUESTIONS:

  1. Is the proper way to nesting/configuring the navigators to obtain the expected final result? Is it 'safe' and correct to have HomeScreen as component for screens on parent Stack and child BottomTab too?

  2. It seems to be a heavy solution (5 Stacks inside a BottomTab inside a Stack inside a Drawer and soon I will add another stack for authorization screens), that slow down running the app: is there a more efficient way to organize navigators using pre-built navigators or else building ie. a custom component for tabBar so that possibly all screens are inside less stack (one?) or anything else that could help me to build lighter solution?

I published on expo.io the full (and simple) sample code implementation, below is the partial code:

const DrawerNav = createDrawerNavigator();
const Drawer = ({ navigation }) => {
  return (
    <DrawerNav.Navigator>
      <DrawerNav.Screen name="MainStack" component={MainStack} />
      <DrawerNav.Screen name="OtherScreen" component={OtherScreen} />
    </DrawerNav.Navigator>
  );
};

const MainStackNav = createStackNavigator();
const MainStack = ({ navigation }) => {
  return (
    <MainStackNav.Navigator headerMode="none">
      <MainStackNav.Screen name="MainHome" component={HomeScreen} />
      <MainStackNav.Screen name="MainBottomTab" component={BottomTab} />
    </MainStackNav.Navigator>
  );
};

const BottomTabNav = createBottomTabNavigator();
const BottomTab = ({ navigation }) => {
  return (
    <BottomTabNav.Navigator>
      <BottomTabNav.Screen name="Home" component={HomeScreen}
        listeners={({ navigation }) => ({
        tabPress: (e) => {
          e.preventDefault();
          navigation.popToTop();
        },
      })}/>
      <BottomTabNav.Screen name="Stack1" component={Stack1} />
      <BottomTabNav.Screen name="Stack2" component={Stack2} />
      <BottomTabNav.Screen name="Stack3" component={Stack3} />
      <BottomTabNav.Screen name="Stack4" component={Stack4} />
      <BottomTabNav.Screen name="Stack5" component={Stack5} />
    </BottomTabNav.Navigator>
  );
};
KoappesT
  • 106
  • 6

1 Answers1

0

Even though this is possible, you should avoid a Tab-Navigator inside a Drawer from Human Interface Guide (iOS) and Experience for both platforms. The special thing with TabBars is that they keep the state when changing the active screen. They should show the main modules of your app. If you have other context or Screens (like Login, etc.), you can add Modal Screens, etc.

The Drawer is the alternative main navigation to a Tab Bar where you have many items that the user wants to access directly (usually more than 5).

I you want to have a menu with additional items you can put it on one (last) tab and call it "More..."

Concerning your other question, the structure is not so complex, I am using more complex structures without problem. You only need to make sure you are not lost yourself in the structure if you change it, so try to keep this code clean. And make sure your user is not lost as well in the navigation.

Christian
  • 4,596
  • 1
  • 26
  • 33
  • About performance improvements I noticed that: (1) TouchableOpacity components manage the onPress faster than normal Buttons; (2) react-native-screens' NativeStacks gave me another improvement. Do you think it is possible to streamline the navigation structure deleting the MainStack navigator: `[Drawer] -> [BottomTab] -> ( HomeScreen , [Stack1] , ... )` and to use Animated to slide out/in the tabBar on screens mounting, avoiding use of tabBarVisible prop, or this still expose me to the risk of screen glitches documented by ReactNavigation? – KoappesT May 20 '21 at 06:09
  • I am not sure about that. The wix-people have created their own native react-navigation because they were not happy with the "standard" react navigation. My experience is that each time you try something not standard with react navigation it has a negative impact somewhere. Animations on component creation are difficult because the system is busy with two things at the same time. – Christian May 20 '21 at 12:41