How to combine StackNavigator and TabNavigator in React Navigation 5?

Viewed 5014

first of all thank you for reading this question, I'm newbie of using react native, now in my case :

I have 4 screens that will show in the tab navigator :

  • Home
  • Profile
  • Artikel
  • Loker

and I want to add non tab navigator ( StackNavigator ) screen to this project for detail of some screen :

  • Profile Detail
  • Artikel Detail
  • Loker Detail

I was trying and when I register this screen , it will show in the tab navigator, I won't to show that detail screen in the tab navigator.

I'm really confuse right now, how to combine stacknavigator and tabnavigator ?

here's my code :

import * as React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import TabBarIcon from '../components/TabBarIcon';

//screen tab
import HomeScreen from '../screens/HomeScreen';
import Artikel from '../screens/Artikel';
import Alumni from '../screens/Alumni';
import Loker from '../screens/Loker';

//non screen tab
import Profile from '../screens/Profile';

const Stack = createStackNavigator();

const BottomTab = createBottomTabNavigator();

const INITIAL_ROUTE_NAME = 'Home';

export default function BottomTabNavigator({ navigation, route }) {

  navigation.setOptions({ headerTitle: getHeaderTitle(route) , headerShown : false});

  return (

    <BottomTab.Navigator initialRouteName={INITIAL_ROUTE_NAME} 
      tabBarOptions={{
        activeTintColor: '#58CB70'
      }}>
      <BottomTab.Screen
        name="Home"
        component={HomeScreen}

        options={{
          title: 'Home',
          tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name="ios-home" />,
        }}
      />
      <BottomTab.Screen
        name="Artikel"
        component={Artikel}
        options={{
          title: 'Artikel',
          tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name="ios-paper" />,
        }}
      />
      <BottomTab.Screen
        name="Loker"
        component={Loker}
        options={{
          title: 'Loker',
          tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name="ios-briefcase" />,
        }}
      />
      <BottomTab.Screen
        name="Alumni"
        component={Alumni}
        options={{
          title: 'Alumni',
          tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name="ios-people" />,
        }}
      />

    </BottomTab.Navigator>

  );
}


function getHeaderTitle(route) {
  const routeName = route.state?.routes[route.state.index]?.name ?? INITIAL_ROUTE_NAME;

  switch (routeName) {
    case 'Home':
      return 'How to get started';
    case 'Links':
      return 'Links to learn more';
  }
}

thank you before

2 Answers
const HomescreenNavigator = () =>{
    return(<Stack.Navigator>
               <Stack.Screen component={ProfileDetail}/>
               <Stack.Screen component={ArtikelDetail}/>
           <Stack.Navigator />)

<BottomTab.Navigator initialRouteName={INITIAL_ROUTE_NAME} 
          tabBarOptions={{
            activeTintColor: '#58CB70'
          }}>
          <BottomTab.Screen
            name="Home"
            component={HomeScreenNavigator} />

        </BottomTab.Navigator>

Is this what you mean? You can just create a new Stack "helper" component which would contain your Stack, and then pass that Stack component to the BottomTab.

I don't know if I'm answering but here there's my code for that. I'm using materialBottomTabs that is more customizable, but I think if the same as yours

function getHeaderTitle(route) {

  const routeName = route.state
    ? route.state.routes[route.state.index].name
    : route.params?.screen || 'The Home s App';

  switch (routeName) {
    case 'Favorites':
      return 'Favorites';
    case 'Info':
      return 'Info about the App';
  }
  return routeName;
}

just set the titles into the switch

const Stack = createStackNavigator(); const Tab = createMaterialBottomTabNavigator();

const NavTab = () => {
  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Favorites"
        component={FavoritesScreen}
        options={({route}) => ({
          tabBarLabel: 'Fav',
          tabBarIcon: () => IconFav(),
        })}
      />
      <Tab.Screen
        name="Info"
        component={InfoScreen}
        options={({route}) => ({
          tabBarLabel: 'Info',
          tabBarIcon: () => IconInfo(),
        })}
      />
    </Tab.Navigator>


<NavigationContainer>
 <Stack.Navigator>
    <Stack.Screen
      name="Home"
      component={NavTab}
      options={({route}) => ({
        headerTitle: getHeaderTitle(route),    
      })}
    />
    <Stack.Screen
      name="Detail"
      component={ItemDetailScreen}
    />
  </Stack.Navigator>
</NavigationContainer>;

To set the title of the Screen into the Stack simply add into the component:

  useEffect(() => {
    navigation.setOptions({
      headerTitle: 'Screen Title', // it can be a variable
    });
  }, []);
Related