Search code examples
react-nativereact-native-navigationreact-native-drawer

React Native Drawer Navigation show headerLeft


I have a Drawer navigator which is inside a Stack navigator and I'd like to display a header. Currently I can display everything I want however because the header is defined at the Stack level the navigation inside the header is stack level not drawer level which is preventing me from opening the drawer.

Root stack

<Stack.Navigator
      initialRouteName={"Splash"}
      screenOptions={{}}
      component={SplashScreen}
    >
      { auth ? 
        <Stack.Screen name="Drawer" component={DrawerStack}  options={({ navigation }) => ({
          title: 'My App', 
          headerLeft: () => (
            <HeaderLeft navigation={ navigation } />
          ),
          headerRight: () => (
            <HeaderRight navigation={ navigation } />
          ),
          headerTitleAlign: 'center',
          headerTintColor: 'white',
          headerStyle: {
            backgroundColor: '#5742f5'
          },
        })} />
      : 
        <Stack.Screen name="Auth" component={AuthStack} options={{
          headerShown: false
        }}/>
      }
    </Stack.Navigator>

Drawer stack

<Drawer.Navigator options={{
            headerShown: true,
            headerLeft: () => (
                <HeaderLeft navigation={ navigation } />
            ),
        }}>
            <Drawer.Screen 
                name="Conversations" 
                options={{
                    title: props.title,
                }} 
                component={ChatListScreen}
            />
            <Drawer.Screen 
                name="ChatRoom" 
                options={{
                    drawerLabel: () => null,
                    title: null,
                    drawerIcon: () => null
                }} 
                component={ChatRoomScreen}
            />
        </Drawer.Navigator>

Note in the drawer navigator the line with headerLeft does nothing and is there to show where I attempted to put it thinking it would work. I did think it might be overlaying the stack one so I commented out the stack one and it didn't work.

HeaderLeft

export default function HeaderLeft ({ navigation }) {

    const openMenu = () => {
        navigation.toggleDrawer();
    }

    return (
        <View style={styles.header}>
            <Icon name='menu' onPress={openMenu} size={28} style={styles.icon} color="white"/>
        </View>
    )
}

My question is how can I refactor this to enable me to have the HeaderLeft component work to open the drawer. I will be adding more screens so ideally something I don't have to pass to each screen but if that is what works I am good with it too.


Solution

  • Options in DrawerStack not work. I modified it:

    <Drawer.Navigator
      screenOptions={{
        headerLeft: () => <HeaderLeft />,
      }}>
      // ...
    </Drawer.Navigator>
    

    And a little change in HeaderLeft:

    import { useNavigation } from '@react-navigation/native';
    
    function HeaderLeft() {
      const navigation = useNavigation();
    
      const openMenu = () => {
        navigation.toggleDrawer();
      };
    
      // render your Button
    }
    

    Demo: https://snack.expo.dev/@pqv2210/0d613b