Search code examples
reactjsreact-nativereact-navigationreact-navigation-bottom-tabreact-native-tabnavigator

Tab bottom navigation react native


I new in react-native and junior developer. I'm using react-native v0.70.6

@react-navigation/stack and @react-navigation/bottom-tabs.

My tab bottom component looks like this:

<Tab.Navigator
                initialRouteName='Home'
                screenOptions={{
                    headerShown:false, 
                    tabBarShowLabel:false,
                    tabBarStyle:style.tabsBottomContainer
                }}
                sceneContainerStyle={style.backgroundContent}
                >
                   <Tab.Screen 
                    name='Assets'
                    component={AssetScreen}
                    options={{unmountOnBlur:true,tabBarIcon:({focused,color})=>(
                        <View>
                           <Image
                                source={iconAsset}
                                style={{
                                    tintColor: focused ? '#00B2DF' : '',
                                    marginTop: 8
                                }}
                                />
                        </View>
                    )}}
                    />
                   <Tab.Screen 
                    name='Bluetooth'
                    component={ConnectScreen}
                    children = {()=> <NotFoundGateway />}
                    options={{unmountOnBlur:true,tabBarIcon:({focused,color})=>(
                        <View>
                           <Image
                                source={iconBluetooth}
                                style={{
                                    tintColor: focused ? '#00B2DF' : ''
                                }}
                                />
                        </View>
                    )}}
                    />
                    <Tab.Screen 
                        name='Home'
                        component={HomeScreen}
                        options={{unmountOnBlur:true,tabBarIcon:({focused,color})=>(
                            <View>
                               <Image
                                    source={iconHome}
                                    style={{
                                        tintColor: focused ? '#00B2DF' : ''
                                    }}
                                    />
                            </View>
                        )}}
                    />
            </Tab.Navigator>    

Inside index.tsx I have a navigation that does not need the bottom tabs. For example the Login. -->

<NavigationContainer>
        <Stack.Navigator initialRouteName='tabsBottomHome'>
          {state.isSignIn ? (
            <>
              <Stack.Screen
              name='tabsBottomHome'
              component={TabsBottomHome}
              options={headerOptions}
              />
              ):(
               <Stack.Screen
                name="Login"
                component={LoginScreen}
                options={{ headerShown: false }}
              />
              <Stack.Screen
                name="LoginError"
                component={LoginError}
                options={headerOptions}
              />
             )
            </>
          )}
</Stack.Navigator>
</NavigationContainer>

The components between the bottom tabs are displayed perfectly. But since I add secondary components to my navigation. For example, I enter the Bluetooth component, within that component I have to enter another component, without losing the bottom tabs.

What would be the correct way to do it? And how could I set all the routes inside my tabs bottom component?


Solution

  • Solved! I had to change my navigation structure as follows : my main structure is like this-->

       <NavigationContainer>
                        <Stack.Navigator initialRouteName='tabsBottomHome'
                          screenOptions={{
                            headerTitle: () => <Header />,
                            headerBackground: () => <HeaderBackground />,
                            headerLeft: ({ onPress, canGoBack }) =>
                              canGoBack ? (
                                <Pressable onPress={onPress} style={{ width: 30, height: 15 }}>
                                  <ArrowLeft height={15} width={15} style={{ marginLeft: 15 }} />
                                </Pressable>
                              ) : (
                                <Pressable style={{ width: 65, height: 35 }}></Pressable>
                              ),
                            headerRight: () => <HeaderRight />,
                          }}
                        >
                          {state.isSignIn ? (
                            <>
                              <Stack.Screen
                              name='tabsBottomHome'
                              component={TabsBottomHome}
                              options={{headerShown: false }}
                              />
                            </>
                          ) : (
                            <>
                              <Stack.Screen
                                name="Login"
                                component={LoginScreen}
                                options={{ headerShown: false }}
                              />
                              <Stack.Screen
                                name="LoginError"
                                component={LoginError}
                              />
                            </>
                          )}
                        </Stack.Navigator>
                      </NavigationContainer>
    

    my tab bottom navigation structure looks like this

      <Tab.Navigator
                        initialRouteName='Home'
                        screenOptions={{
                            headerShown:true, 
                            tabBarShowLabel:false,
                            tabBarStyle:style.tabsBottomContainer,
                            unmountOnBlur: true,
                            headerTitle: () => <Header />,
                            headerBackground: () => <HeaderBackground />,
                            headerLeft: () =>
                                routeName != "Home" ? (
                                    <Pressable onPress={navigateBack} style={{ width: 65, height: 15 }}>
                                      <ArrowLeft height={15} width={15} style={{ marginLeft: 15 }} />
                                    </Pressable>
                                ) 
                                : (
                                    <Pressable style={{ width: 65, height: 35 }}></Pressable>
                                )
                              ,
                            headerRight: () => <HeaderRight />,
                        }}
                        sceneContainerStyle={style.backgroundContent}
                        screenListeners={({route})=>({
                            state: ()=> {
                                setRouteName(route.name);
                            }
                          })}
                        backBehavior={'history'}
                        >
                           <Tab.Screen 
                            name='Assets'
                            component={AssetScreen}
                            options={{tabBarIcon:({focused,color})=>(
                                <View>
                                   <Image
                                    source={iconAsset}
                                    style={{
                                        tintColor: focused ? '#00B2DF' : '',
                                        marginTop: 8
                                    }}
                                        />
                                </View>
                            )}} />
                           <Tab.Screen 
                            name='GatewayStack'
                            component={ConnectGatewayStack}
                            options={{tabBarIcon:({focused,color})=>(
                                <View>
                                   <Image
                                    source={iconBluetooth}
                                    style={{
                                        tintColor: focused ? '#00B2DF' : ''
                                    }}
                                        />
                                </View>
                 )}} />
        
               </Tab.Navigator> 
    

    And my ConnectGatawayStack structure contains the navigation of all that Tab, therefore it is inside my Tab and the focus is not lost and it works correctly. Obviously now I am facing a goBack problem. but that's another kind of problem.

    ConnectGatawayStack -->

      export type StackConnectList = {
            Connect: undefined;
            QRScan: undefined;
            GatewayList: undefined;
            GatewayInfo: undefined;
            NotFoundGateway: undefined;
            GatewayDetected: undefined;
            ErrorConnecting: undefined;
        }
        
        const GatewayStack =  createStackNavigator<StackConnectList>();
        const ConnectGatewayStack = ()  =>{
            return (
            <GatewayStack.Navigator  initialRouteName='Connect'
             screenOptions={{headerShown:false}}
             >
                <GatewayStack.Screen name='Connect' component={ConnectScreen} /> 
                <GatewayStack.Screen name='GatewayList' component={GatewayList} />
                <GatewayStack.Screen name='GatewayInfo' component={GatewayInfo} />
                <GatewayStack.Screen name='QRScan' component={QRScanScreen} />
                <GatewayStack.Screen name='NotFoundGateway' component={NotFoundGateway} />
                <GatewayStack.Screen name='GatewayDetected' component={GatewayDetected} />
                <GatewayStack.Screen name='ErrorConnecting' component={ErrorConnecting} />
            </GatewayStack.Navigator>
            )
        }
        
        export  {ConnectGatewayStack};
    

    Thanks!