5

I am using nested navigation. The root navigator is a StackNavigator and child is DrawerNavigator as far as I know there is no way to put a header bar via DrawerNavigator. So I made it via StackNavigator but I can not update the header title when I navigate a screen that in the DrawerNavigator. How can I update header title in a DrawerScreen

Root Navigator:

 <Stack.Navigator screenOptions={screenOptions} initialRouteName="Login">
    <Stack.Screen name="Login" component={Login} />
    // ...
    <Stack.Screen // This is the screen that contains a child navigator
      name="Main"
      component={Main}
      options={({navigation}) => ({
        title: 'Main Page',
        headerLeft: () => <MenuIcon stackNavigation={navigation} />,
      })}
    />
  </Stack.Navigator>

Child Navigator:

<Drawer.Navigator>
     //...
      <Drawer.Screen
        name="Bids"
        component={Bids}
        options={{
          title: text.bids, // This updates the title that in the drawer navigator menu not the header bar title.
          headerTitle: () => <SearchBar />, //Also this doesn't work I can not update header bar specific to a DrawerComponent.
        }}
      />
      //...
    </Drawer.Navigator>

I try to pass navigation prop of Stack Screen to Drawer Screens but I could not find any way to do this.

 <Drawer.Screen
        component={<Bids stackNavigation={navigation} />} // This does not compile :(
        //...
      />

I try to use setOptions:

const Bids = ({navigation}) => {
  navigation.setOptions({title: 'Bids'});
  //...
};

But again it updates the title in the drawer menu not the Header Bar title.

How can I update Header Bar from a Drawer Screen?

Community
  • 1
  • 1
Muhammed Ozdogan
  • 5,341
  • 8
  • 32
  • 53

1 Answers1

4

I am able to get it. I have the following setup.

  • First -> A Stack = Pre-Home + Home tabs
  • Second -> Bottom tabs
  • Third -> Stack for individual tabs, lets call it inner stack

So, i have a Stack <-> Bottom Tabs <-> Inner Stack.

On Screen change of inner stack, i need to update header which is part of my Parent Stack/Root Stack.

This can be done with the following in the Parent Stack. In your root/Parent Stack have the below

<Stack.Screen 
    name="Tabs"
    component={MyTabs}
    options={({ route, navigation }) => { 
        let currStackState = [];
        let currScreenName = null;
        if (route.state) {
            currStackState = route.state.routes[route.state.index].state;
            const currIndex = currStackState.index;
            currScreenName = (currStackState.routes[currIndex]).name;
        }

        let headerForScreen = getHeaderForRoute(currScreenName);
        // further common things if you want to add can add to above object headerForScreen
        return headerForScreen; 
}} 
/>

your function to header can look like this

const getHeaderForRoute = (routeName, stackName) => {
    //just kept stackName for future purpose, not using it.
  switch (routeName) {
    case 'Scree1':
    case 'MoreScreens':
    case '':
      return {
        headerShown: true,
        headerStyle: DeviceInfo.hasNotch()
          ? [styles1.headerBGColor, styles1.withNotch] : styles1.headerBGColor,
        headerTitle: '',
        headerLeft: () =>
          // Reactotron.log("route", route);
          (
            <View style={{
              flex: 1, marginLeft: 18, flexDirection: 'row',
            }}
            >
              {/* your component */}

            </View>
          ),
        headerRight: () => (

          <View style={{ marginRight: 15, flexDirection: 'row' }}>
            {/* your code*/}
          </View>
        ),
      };
    case 'SomeOther':
      return {
        headerShown: true,
        headerTitle: 'SomeTitle'
      };
    default:
      return {};
  }
};
praveen seela
  • 538
  • 11
  • 24
  • I spent so much time digging for this answer thank you for this detailed answer It helped me a lot. – Omar Aug 10 '20 at 04:31