Home > Back-end >  How can i add a navigation drawer inside a stack navigator in an already existing project
How can i add a navigation drawer inside a stack navigator in an already existing project

Time:01-04

Hello guys so I wanted to add a navigation DRAWER inside my main screen and I did not know how to nest it with the already existing stack navigator , this is my navigation component :

import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";

import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetails from "../screens/shop/ProductDetailScreen";
import { HeaderButtons,Item } from "react-navigation-header-buttons";
import HeaderButton from '../components/UI/HeaderButton'
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";



const RootNavigation=()=> {
    const Stack = createStackNavigator();


    const NavigationDrawerStructure = (props)=> {
      //Structure for the navigatin Drawer
      const toggleDrawer = () => {
        //Props to open/close the drawer
        props.navigationProps.toggleDrawer();
      };
    
      return (
        <View style={{ flexDirection: 'row' }}>
          <TouchableOpacity onPress={()=> toggleDrawer()}>
            {/*Donute Button Image */}
            <Image
              source={{uri: 'https://raw.githubusercontent.com/AboutReact/sampleresource/master/drawerWhite.png'}}
              style={{ width: 25, height: 25, marginLeft: 5 }}
            />
          </TouchableOpacity>
        </View>
      );
    }

    const screenOptions ={
        headerShown:true,
        headerStyle: {
            backgroundColor: 'white',},
            headerTintColor: 'aqua',
          headerTitleStyle: {
            fontWeight: 'bold',
          },

    };

    return(
   
        <NavigationContainer>
        <Stack.Navigator initialRouteName='ProductsOverview' screenOptions={screenOptions}>
            <Stack.Screen name='ProductsOverview' component={ProductsOverviewScreen} options={({navigation,route})=>({title:'All Products',headerTitleStyle:{fontFamily:'open-sans-bold'},
            headerRight:()=>( <HeaderButtons HeaderButtonComponent={HeaderButton}><Item title ='Cart' iconName='md-cart' onPress={()=>{navigation.navigate('CartScreen')}}/></HeaderButtons>)})}/>
            <Stack.Screen name='ProductsDetail' component={ProductDetails} options={({route})=>({title:route.params.productTitle,headerTitleStyle:{fontFamily:'open-sans-bold'}})} />
            <Stack.Screen name='CartScreen' component={CartScreen} options={{title:'Cart Items', headerTitleStyle:{fontFamily:'open-sans-bold'}}} />
            <Stack.Screen name='OrdersScreen'  component={OrdersScreen} options={{title:'Orders '}}/> 
           </Stack.Navigator>
      
    </NavigationContainer>

    )
}

export default RootNavigation;

and this is my app.js


import { StatusBar } from 'expo-status-bar';
import { StyleSheet } from 'react-native';
import {createStore , combineReducers} from 'redux';
import { Provider} from 'react-redux';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';
import productsReducer from './store/reducers/products';
import {composeWithDevTools} from 'redux-devtools-extension'
import RootNavigation from './navigation/ShopNavigation';
import cartReducer from './store/reducers/cart'
import { useState } from 'react';
import ordersReducer from './store/reducers/orders'


const rootReducer=combineReducers({
  products: productsReducer,
  cart: cartReducer,
  orders:ordersReducer,
});

const store = createStore(rootReducer,composeWithDevTools());

const fetchFonts=()=>{
  return Font.loadAsync({
    'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
    'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf')
  })
}

export default function App() {
  const [fontLoaded,setfontLoaded]= useState(false);
  
  if (!fontLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={()=>setfontLoaded(true)}
        one rror={console.warn}
      />
    );
  }
  return (
    <Provider store={store}>
      <RootNavigation />
    </Provider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

can you give me an idea how to nest them together I tried using the docs but still full of errors and Thanks

CodePudding user response:

Drawer Navigator must be a parent to both Stack and Tab navigators. With that knowledge, let we refactor our code as below:

import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";

import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetails from "../screens/shop/ProductDetailScreen";
import { HeaderButtons, Item } from "react-navigation-header-buttons";
import HeaderButton from "../components/UI/HeaderButton";
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";
import { createDrawerNavigator } from "@react-navigation/drawer";

const RootNavigation = () => {
  const Stack = createStackNavigator();

  const Drawer = createDrawerNavigator();

  const AppStack = () => (
    <Stack.Navigator
      initialRouteName="ProductsOverview"
      screenOptions={screenOptions}
    >
      <Stack.Screen
        name="ProductsOverview"
        component={ProductsOverviewScreen}
        options={({ navigation, route }) => ({
          title: "All Products",
          headerTitleStyle: { fontFamily: "open-sans-bold" },
          headerRight: () => (
            <HeaderButtons HeaderButtonComponent={HeaderButton}>
              <Item
                title="Cart"
                iconName="md-cart"
                onPress={() => {
                  navigation.navigate("CartScreen");
                }}
              />
            </HeaderButtons>
          ),
        })}
      />
      <Stack.Screen
        name="ProductsDetail"
        component={ProductDetails}
        options={({ route }) => ({
          title: route.params.productTitle,
          headerTitleStyle: { fontFamily: "open-sans-bold" },
        })}
      />
      <Stack.Screen
        name="CartScreen"
        component={CartScreen}
        options={{
          title: "Cart Items",
          headerTitleStyle: { fontFamily: "open-sans-bold" },
        }}
      />
      <Stack.Screen
        name="OrdersScreen"
        component={OrdersScreen}
        options={{ title: "Orders " }}
      />
    </Stack.Navigator>
  );

  return (
    <NavigationContainer>
      <Drawer.Navigator>
        <Drawer.Screen name="MainStack" component={AppStack} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

export default RootNavigation;

I omitted component code below as can't access drawer.

 const NavigationDrawerStructure = (props)=> {
      //Structure for the navigatin Drawer
      const toggleDrawer = () => {
        //Props to open/close the drawer
        props.navigationProps.toggleDrawer();
      };
    
      return (
        <View style={{ flexDirection: 'row' }}>
          <TouchableOpacity onPress={()=> toggleDrawer()}>
            {/*Donute Button Image */}
            <Image
              source={{uri: 'https://raw.githubusercontent.com/AboutReact/sampleresource/master/drawerWhite.png'}}
              style={{ width: 25, height: 25, marginLeft: 5 }}
            />
          </TouchableOpacity>
        </View>
      );
    }

Here a minified version of working implementation

https://snack.expo.dev/@emmbyiringiro/69dc5b

  •  Tags:  
  • Related