rafaelfndev
rafaelfndev

Reputation: 739

How to use StackNavigator with DrawerNavigator and SwitchNavigator on React Native?

TL;DR: I need this result (with DrawerNavigator and StackNavigator navigation listed below):

enter image description here

Structure:


I have this structure of screens:

In the root pages (represented by " • "), I need the navigation to be done with the DrawerNavigator, and the subpages (represented by " |_ ") I need to be navigated with the StackNavigator.

This is the behavior I would like to get:

• Account
|_ Create Account
|_ Login
|_ Forget Password

• Products
|_ Product detail
 |_ Ingredients

• Configuration
• About

• Cart
|_ Checkout
 |_ Finish Checkout 

Drawer: MainDrawer with => createDrawerNavigator()

• Account
• Products
• Configuration
• About
• Cart

SwitchNavigator:

Start: StartCheck, // Screen component
App: MainDrawer, // Drawer
Welcome: WelcomeScreen, // Screen component

Component: StartCheck and WelcomeScreen is a <Component />

StartCheck: this just check if have data on AsyncStorage, something like "isFirstRun", and open WelcomeScreen or MainDrawer according of result [like this documentation].

My code:


Screens:

const Screens = {
    account: {
        screen: AccountScreen,
        path: 'account'
    },
    products: {
        screen: ProductsScrren,
        path: 'products'
    },
    configuration: {
        screen: ConfigurationScrren,
        path: 'configuration'
    },
    about: {
        screen: AboutScrren,
        path: 'about'
    },
    cart: {
        screen: CartScrren,
        path: 'cart'
    },
};

MainDrawer:

const MainDrawer = createDrawerNavigator({
    ...Screens
}, {
    contentComponent: Sidebar,
    initialRouteName: 'products',
});

App Container with SwitchNavigator:

const AppContainer = createAppContainer(createSwitchNavigator(
    {
        StartCheck: StartCheck, // Component

        App: MainDrawer, // Drawer
        Welcome: WelcomeScreen, // Component
    },
    {
        initialRouteName: 'StartCheck',
    }
));

export default AppContainer;

With this code, the Header does not appear, so I put the DrawerNavigator inside StackNavigator:

MainStack:

const MainStack = createStackNavigator({
    MainDrawer
});

And I modify App Container with SwitchNavigator:

const AppContainer = createAppContainer(createSwitchNavigator(
    {
        StartCheck: StartCheck, // Component

        App: MainStack, // Stack
        Welcome: WelcomeScreen, // Component
    },
    {
        initialRouteName: 'StartCheck',
    }
));

export default AppContainer;

But in this way, the header overlaps the sidebar, and if I use the headerMode: 'none', my header disappears from the other screens as well (not just the container).

enter image description here

I need this result (with DrawerNavigator and StackNavigator navigation list above):

enter image description here

And I also do not know where I can put the secondary screens (to open with the navigation method of StackNavigator).

Sorry for the big post, is that I tried to detail as much as possible, since I have been looking for a solution for some time but I have not found...

Upvotes: 1

Views: 2100

Answers (2)

Vinil Prabhu
Vinil Prabhu

Reputation: 1289

Define your createSwitchNavigator like this

const AppContainer = createAppContainer(createSwitchNavigator(
    {
        StartCheck: StartCheck, // Component

        App: MainStack, // Stack
        Welcome: WelcomeScreen, // Component
    },
    {
        initialRouteName: 'StartCheck',
        headerMode: 'none',
    }
));

Upvotes: 0

Hend El-Sahli
Hend El-Sahli

Reputation: 6752

I will describe my idea in a textual form first:

After your Start screen is done with it's job, your're going to be in the drawer navigator, which is your root node

  • Your drawer would either render StackNavigator or Pure Component|Screen. So, Drawer should have these routes:
  • AccountStack | AuthStack.
  • ProductsStack.
  • Configuration Screen.
  • About Screen.
  • CheckoutStack.

To show the header all the way

  • All StackNavigator is shipped with header /// done for screens rendered within stack.

  • For your pure components like About screen, you could create a custom header and add it manually within these components.

OR "not recommended from my point of view"

  • Render each pure screen like About screen within a stacknavigator just to save yourself the time for creating a custom header.

    const MainDrawer = createDrawerNavigator({
      Account: AccountStack,
      Product: ProductsStack,
      Configuration: ConfigScreen, // Pure Component
      About: AboutScreen, // Pure Component
      Cart: CartStack
    });
    
    // Ex stack:
    const AccountStack = createStackNavigator({
      CreateAcount: SignUpScreen,
      Login: LoginScreen,
      ForgotPassword: ForgotPasswordScreen
    });
    

Upvotes: 1

Related Questions