Ferdi Louwerse
Ferdi Louwerse

Reputation: 99

React navigation drawer navigator with header back button

I'm using the drawer navigation from React Navigation v5. In my root file i've created the drawer navigator. Some of the screens inside of this navigator has a nested stack navigator. The first item is dashboard and the second item is Relations.

The problem is when I go to relations I don't get a back button for going to the first screen (Dashboard). Is it possible to add this to my relations screen?

Root code:

<NavigationContainer>
  <DrawerNavigator.Navigator
    drawerContent={(props) => (
      <SidebarComponent {...props} user={this.props.device.user} />
    )}
    drawerPosition="right"
    drawerStyle={{width: '90%', padding: 0, backgroundColor: 'red'}}>
    {this.props.authenticated && this.props.device.api_key ? (
      <>
        <DrawerNavigator.Screen
          name="Home"
          options={{
            headerShown: false,
            icon: 'tachometer-alt',
            category: 'dashboard',
          }}
          component={DashboardStack}
        />
        <DrawerNavigator.Screen
          name="Relations"
          options={{
            icon: 'address-book',
            category: 'dashboard',
          }}
          component={RelationsStack}
        />
      </>
    ) : (
      <>
        <DrawerNavigator.Screen
          name="login"
          options={{headerShown: false, gestureEnabled: false}}
          component={LoginStack}
        />
      </>
    )}
  </DrawerNavigator.Navigator>
</NavigationContainer>

Relation stack code:

import 'react-native-gesture-handler';
import React from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import RelationsListScreen from '../RelationsListScreen';
import {colors} from '../../../assets/styles/variables';

const Stack = createStackNavigator();

function RelationsStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        options={{
          headerShown: true,
          headerTintColor: '#FFF',
          headerStyle: {
            backgroundColor: colors.primary,
            shadowColor: 'transparent',
          },
        }}
        name="Relations"
        component={RelationsListScreen}
      />
    </Stack.Navigator>
  );
}

export default RelationsStack;

Upvotes: 4

Views: 5537

Answers (1)

bas
bas

Reputation: 15722

You could create a stack navigator that is a screen of your drawer navigator (when the user is authenticated) which has Home and Relations as screens. I've called this navigator AuthenticatedNavigator in the example below:

const AuthenticatedStack = createStackNavigator();
// ...

const AuthenticatedNavigator = () => {
  return (
    <AuthenticatedStack.Navigator screenOptions={{headerShown: false}}>
      <AuthenticatedStack.Screen
        name="Home"
        options={{
          icon: 'tachometer-alt',
          category: 'dashboard',
        }}
        component={DashboardStack}
      />
      <AuthenticatedStack.Screen
        name="Relations"
        options={{
          icon: 'address-book',
          category: 'dashboard',
        }}
        component={RelationsStack}
      />
    </AuthenticatedStack.Navigator>
  );
};

function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItem
        label="Home"
        onPress={() => props.navigation.navigate('Home')}
      />
      <DrawerItem
        label="Relations"
        onPress={() => props.navigation.navigate('Relations')}
      />
    </DrawerContentScrollView>
  );
}

function App() {
  const authenticated = true;
  return (
    <NavigationContainer>
      <DrawerNavigator.Navigator
        drawerPosition="right"
        drawerStyle={{width: '90%', padding: 0, backgroundColor: 'red'}}
        drawerContent={(props) => <CustomDrawerContent {...props} />}>
        {authenticated ? (
          <DrawerNavigator.Screen
            name="authenticated"
            component={AuthenticatedNavigator}
          />
        ) : (
          <DrawerNavigator.Screen
            name="login"
            options={{headerShown: false, gestureEnabled: false}}
            component={LoginStack}
          />
        )}
      </DrawerNavigator.Navigator>
    </NavigationContainer>
  );
}

I've also used a custom drawer content component so the links in the drawer still work correctly after using the approach of creating another stack navigator. You can read more about providing a custom drawer component in the documentation here: https://reactnavigation.org/docs/drawer-navigator/#providing-a-custom-drawercontent.


I've left out some code and made authenticated a hardcoded value to simplify the example. Also be sure to import DrawerItem, DrawerContentScrollView from @react-navigation/drawer.

Upvotes: 3

Related Questions