13

I am working on a Practice Project like Login/Register Application and I am using Stack Navigation from react-navigations and it's working perfect,

Now when User Login's he should be redirected to the Dashboard Screen where I want a Drawer to the right side of the header "I also added a screenshot" and I created the Dashboard Screen also in Stack Navigation I don't know How I can add that Drawer inside the Stack Navigation I just want Drawer on my Dashboard Screen so anyone who can help with that? Thanks

This is What I want to look on my Dashboard Screen

App.js (Where I added all Stack Screens)

    import React from 'react';

    import { createStackNavigator, createDrawerNavigator } from 'react-navigation';

    import HomeScreen from './screens/HomeScreen';
    import LoginScreen from './screens/LoginScreen';
    import RegisterScreen from './screens/RegisterScreen';
    import Dashboard from './screens/Dashboard';

    const StackNavigation = createStackNavigator({
      HomeStack: HomeScreen,
      LoginStack: LoginScreen,
      RegisterStack: RegisterScreen,
      DashboardStack: Dashboard,

    }, {
        initialRouteName: 'HomeStack',
      });

      const DrawerNav = createDrawerNavigator({
        DashboardStack: Dashboard,
      })


    export default class App extends React.Component {
      render() {
        return (
          <StackNavigation />
        );
      }
    }

Dashboard.js

    import React from 'react';
    import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';

    import Icon from 'react-native-vector-icons/FontAwesome';

    export default class Dashboard extends React.Component {

        static navigationOptions = {

            headerTitle: 'Dashboard',
            headerLeft: null,

            headerTitleStyle: {
                flex: 1,
                color: '#fff',
                textAlign: 'center',
                alignSelf: 'center',
                fontWeight: 'normal',
            },

            headerStyle: {
                backgroundColor: '#b5259e',
            },
        }
Irshad Alam
  • 143
  • 1
  • 2
  • 9

3 Answers3

12

Showing drawer from right side.

Add a drawer Position parameter when create Drawer Navigator.

const DrawerNav = createDrawerNavigator({
  DashboardStack: Dashboard, 
},
{
  drawerPosition: 'right'
});

Call DrawerNavigation from header's button.

Add a button to the header for toggleDrawer in Dashboard.js. You can get the navigation instance as below in navigationOptions;

class Dashboard extends React.Component {
  static navigationOptions = ({navigation, navigationOptions}) => {
    return {
      headerTitle: 'Dashboard@@',
      headerLeft: <Text>Left</Text>,
      headerRight: (
        <Button onPress = {navigation.toggleDrawer}
        title="Menu"
        color="#fff">
          <Text>Menu</Text>
        </Button>
      ),
      headerTitleStyle: {
        flex: 1,
        color: '#fff',
        textAlign: 'center',
        alignSelf: 'center',
        fontWeight: 'normal',
      },

      headerStyle: {
        backgroundColor: '#b5259e',
      },
    }
  }

You could change button to Touchable Opacity or another one.

Wrap AuthStackNavigation and DrawerNavigation using another Navigator.

Wrap your navigation using createSwitchNavigation or another and export.

// App.js

import React from 'react';

import {
  createStackNavigator,
  createDrawerNavigator,
  createSwitchNavigator,
} from 'react-navigation';

import HomeScreen from './srcs/screens/Home';
import Dashboard from './srcs/screens/Dashboard';

const AuthStackNavigation = createStackNavigator({
  HomeStack: HomeScreen,
  LoginStack: HomeScreen,
  RegisterStack: HomeScreen,
}, {
  initialRouteName: 'HomeStack',
})

const DashboardStack = createStackNavigator({ // For header options
  Dashboard: Dashboard
})

const DrawerNav = createDrawerNavigator({
  DashboardStack: DashboardStack,
  SecondScreen: Dashboard, // You should use another screen.
  ThirdScreen: Dashboard,
})

const MainNavigation = createSwitchNavigator({
  HomeDrawer: DrawerNav,
  AuthStack: AuthStackNavigation, // You will use this.props.navigation.replace('HomeDrawer') after login process.
})

export default MainNavigation // Stack, Drawer, Switch naviagtions return react component.
Jeff Gu Kang
  • 4,749
  • 2
  • 36
  • 44
  • and where I have to call DrawNav? like I called StackNavigator in App.js render. – Irshad Alam Sep 23 '18 at 22:00
  • I called DrawNav same as StackNavigator in the App render like this ", " when I run my app my Dashboard shows the drawer but my Dashboard header got hidden without even swiping drawer. – Irshad Alam Sep 23 '18 at 22:05
  • @IrshadAlam I wrote how to call multiple navigation. You can apply this what you want. And you can put screens more and control in your `DrawerNav` as my example. – Jeff Gu Kang Sep 24 '18 at 05:31
  • I done same as you coded in the App.js file, and I added a Icon of hamburger in the dashboard header and when I pass {this.props.navigation.toggleDrawer} or {this.props.navigation.navigate('DrawerOpen')} I get the error (undefined is not a object this.props.navigation). what should I do? I want it to opena drawer with some components when the icon pressed/tapped. Thanks – Irshad Alam Sep 24 '18 at 13:37
  • @IrshadAlam I updated my answer after test on my laptop. It will show you how you can edit header's buttons for navigation control and how you can wrap screens through react-navigation. Good luck :) – Jeff Gu Kang Sep 25 '18 at 06:31
  • it's working but I get something like this dashboard header's gone hidden anywhere even I didn't open the drawer have a look please http://prntscr.com/kyorpd and after swiping the drawer It's still hidden anywhere and has to swipe to show the drawer ( http://prntscr.com/kyotqv ) but I made the header in my Dashboard Screen. Header( http://prntscr.com/kyosez ), and one thing When I rebuild my app it open's directly dashboard screen not home screen like I want to show the Home first then Login then Dashboard like it did the initialRoute Home stack in StackNavigation. Thanks – Irshad Alam Sep 25 '18 at 20:44
  • @IrshadAlam Did you check `App.js` in my answer? It was changed also :) – Jeff Gu Kang Sep 26 '18 at 01:44
  • Thanks @Jeff Gu Kang it's working perfect but the last problem is that it's stuck with Dashboard screen with initialRoute I want the initialRoute as HomeStack. as mentioned the initialRoute: 'HomeStack' it's not working idk why? – Irshad Alam Sep 26 '18 at 12:01
  • and I think that is because we given the DashboardStack in drawer's first screen how do I un select that? like I just want to show the drawer user selects what screen to open. – Irshad Alam Sep 26 '18 at 12:26
  • @IrshadAlam Actually, I may already answered perfectly about your questions. And this looks another one. Check `App.js` again in my answer. And change `MainNavigation`'s order or give options as `initialRouteName`. You could control react-navigation using various ways after understanding how it works. – Jeff Gu Kang Sep 27 '18 at 01:46
  • And put `homeStack` in `DrawerNavi` if you want to show it from `DrawerNavigation`'s list. – Jeff Gu Kang Sep 27 '18 at 01:48
  • Hello @Jeff Gu Kang , Actually I was creating a custom Drawer which I finally complete Today, actually I am new to react native and don't have knowledge about react navigation yet, I am confused with the same issue You answer is working fine, but the thing is that am still stuck with that Dashboard screen when I change the Orders in MainNavigation like first Drawer then Stack {Drawer: DrawerNav, AuthStack: StackNav} my menu Icon didn't work how can I solve this? Thanks, :) – Irshad Alam Oct 02 '18 at 23:29
  • @IrshadAlam It will be better to split to another question. and how about considering marking answer if you get a solution about you first question? – Jeff Gu Kang Oct 04 '18 at 06:34
  • oh yeah sorry I forgot to do that and yeah let me split this question. – Irshad Alam Oct 04 '18 at 12:47
4

For those looking for the solution in react-navigation 5.X, you can do it like this:

Drawer Navigator

const ProductListWithDrawer = () => {
 return (
  <Drawer.Navigator initialRouteName="ProductList">
   <Drawer.Screen name="ProductList" component={screens.ProductList} />
   <Drawer.Screen name="ProductDetail" component={screens.ProductDetailScreen} />
  </Drawer.Navigator>
  );
 };

Stack Navigator (should be wrapped inside a Navigation Container)

<Stack.Navigator initialRouteName="Dashboard" screenOptions={{ headerShown: false }}>
  <Stack.Screen name="Dashboard" component={screens.Dashboard} />
  <Stack.Screen name="Loading" component={screens.Loading} />
  <Stack.Screen name="Chat" component={screens.Chat} />
  <Stack.Screen name="ProductListWithDrawer" component={ProductListWithDrawer} /> //our drawer
</Stack.Navigator>

Basically, this should get the work done. One more thing that could be the issue here is while navigating to those screens inside drawer navigator with params. In that case, it can be done like this:

navigation.navigate("ProductListWithDrawer", {
              screen: "ProductList",
              params: { user: "Alex"},
            });

This has also been explained in Nesting navigators.

Niraj Niroula
  • 2,376
  • 1
  • 17
  • 36
3

I have just created an example that probably cases you need.

import React, {Component} from 'react';
import {
  StyleSheet,
  Button,
  Image,
  TouchableWithoutFeedback,
  View,
} from 'react-native';
import {
  createDrawerNavigator,
  createStackNavigator,
  StackActions,
  NavigationActions,
} from 'react-navigation';


class HomeScreen extends React.Component {
  render() {
    return (
        <View style={styles.container}>
          <Button
              onPress={() => this.props.navigation.navigate('Notifications')}
              title="Go to notifications"
          />
        </View>
    );
  }
}

class NotificationsScreen extends React.Component {
  render() {
    return (
        <View style={styles.container}>
          <Button
              onPress={() => this.props.navigation.navigate('Home')}
              title="Go back home"
          />
        </View>
    );
  }
}

class LoginScreen extends Component {
  openDashboard = () => {
    const resetAction = StackActions.reset({
      index: 0,
      actions: [NavigationActions.navigate({routeName: 'Dashboard'})],
    });
    this.props.navigation.dispatch(resetAction);
  }

  render() {
    return (
        <View style={styles.container}>
          <Button
              onPress={this.openDashboard}
              title={'Login'}
          />
        </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingHorizontal: 20,
  },
  icon: {
    width: 24,
    height: 24,
  },
  menu: {
    marginRight: 8,
  }
});

const renderMenu = (navigation) => (
    <TouchableWithoutFeedback onPress={() => navigation.openDrawer()}>
      <Image
          source={require('./menu.png')}
          style={[styles.icon, styles.menu]}
      />
    </TouchableWithoutFeedback>
)

const Home = createStackNavigator({
  Home: {
    screen: HomeScreen,
    navigationOptions: ({navigation}) => ({
      title: 'Home',
      headerRight: renderMenu(navigation)
    }),
  }
})

const Notifications = createStackNavigator({
  Notifications: {
    screen: NotificationsScreen,
    navigationOptions: ({navigation}) => ({
      title: 'Notifications',
      headerRight: renderMenu(navigation)
    })
  }
})

const Dashboard = createDrawerNavigator(
    {
      Home: {
        screen: Home,
        navigationOptions: {
          drawerLabel: 'Home',
          drawerIcon: (
              <Image
                  source={require('./chats-icon.png')}
                  style={styles.icon}
              />
          ),
        }
      },
      Notifications: {
        screen: Notifications,
        navigationOptions: {
          drawerLabel: 'Notifications',
          drawerIcon: (
              <Image
                  source={require('./notif-icon.png')}
                  style={styles.icon}
              />
          ),
        }
      },
    },
    {
      drawerPosition: 'right'
    }
);

const App = createStackNavigator(
    {
      Login: LoginScreen,
      Dashboard: Dashboard
    },
    {
      initialRouteName: 'Login',
      headerMode: 'none'
    }
)

export default App;
  • When user presses login button on LoginScreen the navigation will be reseted (so that the user can't goes back to the login screen via the back arrow or the physical back button on android).
  • Then we create a Drawer to the right with two screens and with a hamburger icon.
  • The sub screens for the Home should be inside the Home stack and the same for the notifications.

You just need to add the missing icons.

Naoufal
  • 417
  • 3
  • 6
  • Actually I am new to React Native and where I am confused in is I have the Dashboard Screen, I have the Icon on the right side top header, this is what I want to know that.. When I click the hamburger Icon a small drawer to bee opened please check my App.js file and and let me know where should I call it? I applied changes made by Jeff Gu Kang and it's working I don't know where should I call DrawNav so the only Dashboard screen can access to the drawer.. Thanks – Irshad Alam Sep 23 '18 at 23:16