How to get the current route name of a Stack Navigator that is inside a Bottom Tab Navigator?

Viewed 48

I have a Bottom Tab Navigation like this:

const tabs: {
    name: keyof RootNavigationParams;
    component: any;
  }[] = [
    {
      name: "BalanceStackNavigator",
      component: BalanceStackNavigator,
    },
    {
      name: "BudgetScreen",
      component: BudgetScreen,
    },
    {
      name: "EntriesScreen",
      component: EntriesScreen,
    },
    {
      name: "SettingsScreen",
      component: SettingsScreen,
    },
  ];

  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        header: (props) => <Header {...props} />,
        tabBarIcon: ({ focused }) => renderIcons(focused, route),
        tabBarStyle: {
          borderTopWidth: 0,
          elevation: 0,
          backgroundColor: colors.background,
        },
      })}>
      {tabs.map(({ name, component }) => (
        <Tab.Screen
          key={name}
          name={name}
          options={{ tabBarShowLabel: false }}
          component={component}
        />
      ))}
    </Tab.Navigator>
  );

Inside this Bottom Tab Navigator I have the next Stack Navigator:

 <Stack.Navigator screenOptions={{ headerShown: false }}>
    <Stack.Screen name="BalanceScreen" component={BalanceScreen} />
    <Stack.Screen name="AddExpenseScreen" component={AddExpenseScreen} />
 </Stack.Navigator>

Now, what I want to do is on the Header that is on the Bottom Tab Navigation, I want to change the header depending on which screen the app is.

const Header = ({ route }: BottomTabHeaderProps) => {
  return (
    <View>
      <Text>
        {route.name}
      </Text>
    </View>
  );
};

The problem here is if I'm under some of the routes inside BalanceStackNavigator the route name is "BalanceStackNavigator", not the name of the current screen inside BalanceStackNavigator. Is there a way to get the current route name even if its inside a Stack Navigator?

1 Answers

If you want the name of screens from your nested BalanceStackNavigator you should pass Header to it:

<Stack.Navigator screenOptions={{ header: (props) => <Header {...props} /> }}>
   <Stack.Screen name="BalanceScreen" component={BalanceScreen} />
   <Stack.Screen name="AddExpenseScreen" component={AddExpenseScreen} />
 </Stack.Navigator>

Then you could hide the header of the Tab when you are in BalanceStackNavigator, like so:

<Tab.Navigator
  screenOptions={({ route }) => ({
    header: (props) => <Header {...props} />,
    tabBarIcon: ({ focused }) => renderIcons(focused, route),
    tabBarStyle: {
      borderTopWidth: 0,
      elevation: 0,
      backgroundColor: colors.background,
    },
  })}
>
  {tabs.map(({ name, component }) => (
    <Tab.Screen
      key={name}
      name={name}
      options={{ tabBarShowLabel: false, headerShown: name !== "BalanceStackNavigator" }}
      component={component}
    />
  ))}
</Tab.Navigator>;
Related