React-native-navigation: [V2] need more complete example for sideMenu in docs

Created on 23 Aug 2018  路  29Comments  路  Source: wix/react-native-navigation

Issue Description

After reading the docs and checking the code I am still stuck in understanding how to make a layout where you can navigate to a screen from side menu.

Steps to Reproduce / Code Snippets / Screenshots

I have this function I call from a button in side menu component.

goToContactUS = () => {
   console.log(this.props.componentId)
  Navigation.push(this.props.componentId, {
     component: {
         name: 'screen.ContactUS',
     }
   })
}

Currently this is my layout

Navigation.setRoot({
  root: {
    sideMenu: {
      left: {
        component: {
          name: 'screen.SideMenu',
        }
      },
      center: {
        bottomTabs: {
          id: 'tabs',
          options: {
            topbar: {
              visible: true,
            }
          },
          children: [
            {
              stack: {
                id: 'tab1',
                children: [
                  {
                    component: {
                      name: 'screen.Home',
                      options: {
                        topbar: {
                          visible: true
                        },
                        bottomTab: {
                          fontSize: 12,
                          text: 'Home',
                          icon: homeIcon,
                          textColor: theme.$tabColor,
                          selectedTextColor: '#000',
                          selectedIconColor: '#000',
                        }
                      }
                    },
                  },
                ]
              }
            },
            {
              stack: {
                id: 'tab2',
                children: [
                  {
                    component: {
                      name: 'screen.Events',
                      options: {
                        bottomTab: {
                          text: 'Events',
                          fontSize: 12,
                          icon: eventsIcon,
                          textColor: theme.$tabColor,
                          selectedTextColor: '#000',
                          selectedIconColor: '#000',
                        }
                      }
                    },
                  },
                ]
              }
            },
          ],
        },
      }
    }
  }
});

How do I make a layout where in I can navigate to the ContactUs screen from Side menu component?


Environment

  • React Native Navigation version: 2.0.2474
  • React Native version: 0.56
  • Platform(s) (iOS, Android, or both?): both
  • Device info (Simulator/Device? OS version? Debug/Release?): dev
馃彋 stale

Most helpful comment

Have you checked here? Then just

Navigation.push(center_stack_id,{
component{
    name: registeredComponentName
})

All 29 comments

@jerbombs - You need to pass the componentId of the screen on top of which you want to push the new screen. Say, for example, you want to push on top of the tab1, try putting tab1 as your componentId in the push.

@rgoldiez thanks for reply, but what if i want to add a screen outside of the tabs. for example I have 3 buttons in side menu. logout, contactus, and profile. and I want to navigate to contactus? Where should I put the ContactUS component here? inside the center?

@jerbombs - Try adding a stack under center and add id to the stack object. You should be able to setStackRoot() using the newly added stack id or you could push a screen onto the stack (over the bottomTabs.

i tried this

center: {
        stack: {
           id: 'dummyStack',
          children: [
             {
                component: {
                   name: 'screen.ContactUs'
                }
             },
             {

        bottomTabs: {
          id: 'tabs',
          options: {
            topbar: {
              visible: true,
            }
          },
          children: [
            {
              stack: {
                id: 'tab1',
                children: [
                  {
                    component: {
                      name: 'screen.Home',
                      options: {
                        topbar: {
                          visible: true
                        },
                        bottomTab: {
                          fontSize: 12,
                          text: 'Home',
                          icon: homeIcon,
                          textColor: theme.$tabColor,
                          selectedTextColor: '#000',
                          selectedIconColor: '#000',
                        }
                      }
                    },
                  },
                ]
              }
            },
            {
              stack: {
                id: 'tab2',
                children: [
                  {
                    component: {
                      name: 'screen.Events',
                      options: {
                        bottomTab: {
                          text: 'Events',
                          fontSize: 12,
                          icon: eventsIcon,
                          textColor: theme.$tabColor,
                          selectedTextColor: '#000',
                          selectedIconColor: '#000',
                        }
                      }
                    },
                  },
                ]
              }
            },
          ],
        },
             }
          ]
        },

but I still couldn't Navigate.push to screen.ContactUS and the bottomtab is a mess.

@rgoldiez can you give me an example of sideMenu layout ? the example for the sideMenu in the docs doesn't feel complete

still no progress :(

Hi, I have the same layout as yours, its not a question about "placing" the Contact Us component somewhere in the stack, its about in which stack and from which component are you pushing from?

pushAndCloseSideMenu() {
    this.hideSideMenu();
    Navigation.push('tab1', {
        component: {
            name: screen.ContactUS,
        },
    });
}

The above will push _ContactUs_ from tab1. So even if you are in tab2, and you use the SideMenu to navigate, _Contact US_ will be shown, but in tab1. [You would have to switch to tab1 to see _ContactUS_]

The only problem I am having with this combination of bottomTabs and SideMenu is passing the tab component Id in SideMenu component. I would have to use some kind of state management (redux) to track which tab I am currently in now, so that when I show SideMenu and push to ContactUS, I would push from the active tab I am in now.

Following up on my recent post, I found a simple solution to handle active SideMenu navigation with bottomTabs.

I use a global variable that I define here:

registerScreens(); global.currentSelectedTabIndex = 0; // set default as no tab is clicked on app load Navigation.events().registerBottomTabSelectedListener( ({ selectedTabIndex, unselectedTabIndex }) => (global.currentSelectedTabIndex = selectedTabIndex) );

This would require all my tabs to have IDs in this format _('tab0', 'tab1', 'tab2', ...)_

So, in my SideMenu component, to navigate to any other component, I can do this:

pushAndCloseSideMenu() { this.hideSideMenu(); Navigation.push('tab'.concat(global.currentSelectedTabIndex.toString()), { component: { name: screen.ContactUS }, }); }

Have you checked here? Then just

Navigation.push(center_stack_id,{
component{
    name: registeredComponentName
})

@spiraltrip @angelos3lex thanks for you reply.
@spiraltrip I kind of understand it now. But what If I want contact page to be on top the bottom tabs? How do I design the layout? I tried putting it inside the stack in the center

like this

center: {
        stack: {
           id: 'dummyStack',
          children: [
             {
                component: {
                   name: 'screen.ContactUs'
                }
             },
             {

        bottomTabs: {
          id: 'tabs',
          options: {
            topbar: {
              visible: true,
            }
          },
          children: [
            {
              stack: {
                id: 'tab1',
                children: [
                  {
                    component: {
                      name: 'screen.Home',
                      options: {
                        topbar: {
                          visible: true
                        },
                        bottomTab: {
                          fontSize: 12,
                          text: 'Home',
                          icon: homeIcon,
                          textColor: theme.$tabColor,
                          selectedTextColor: '#000',
                          selectedIconColor: '#000',
                        }
                      }
                    },
                  },
                ]
              }
            },
            {
              stack: {
                id: 'tab2',
                children: [
                  {
                    component: {
                      name: 'screen.Events',
                      options: {
                        bottomTab: {
                          text: 'Events',
                          fontSize: 12,
                          icon: eventsIcon,
                          textColor: theme.$tabColor,
                          selectedTextColor: '#000',
                          selectedIconColor: '#000',
                        }
                      }
                    },
                  },
                ]
              }
            },
          ],
        },
             }
          ]
        },

but the topbar is not looking good. there is no title anymore just this. My topbar should be yellow. Seem like it is on top of another topbar

screen shot 2018-09-02 at 12 24 50 pm

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.

The issue has been closed for inactivity.

Hi all,
any luck with solving this puzzle?
I have a sideMenu and cannot find any documentation/example on how to switch between the screens properly

@alexsmartens - What screens are you trying to switch between? For me, I have a stack in my center view and issue a Navigation.setStackRoot(CENTER_STACK_ID, {options}) to switch the stack in the center view.

@rgoldiez, I have a side menu with some number of screens. I want to navigate between these screens.
I am trying to do exactly what you described, but cannot make it work.
Don't you mind posting a snippet of your code showing how you construct your stack and navigate between the screens?

See my initial layout below. One key point (not well documentation) is to assign an id to the center stack if you want to perform setStackRoot. Then, when your user interacts with the sideMenu items, you can issue a Navigation.setStackRoot('stackRoot', {options}) (in my case) to change the center screen.

Navigation.setRoot({
  root: {
    sideMenu: {
      left: {
        component: {
          name: 'leftDrawer',
          id: 'leftDrawer',
        },
      },
      center: {
        stack: {
          id: 'stackRoot',
          children: [
            {
              component: {
                name: 'entry',
              },
            },
          ],
        },
      },
    },
  },
});

@rgoldiez, Thank you for your explanation! Now screen switching works in my implementation.

So, in this case I don't need to list all my components (screens) in center stack. I do add only my initial component (screen) to the center stack and do Navigation.setStackRoot('stackRoot', {options}) when I need to switch to a different screen. Does it sound reasonable?

@alexsmartens - You've got it exactly right. The center stack just has in the stack what's needed right now (possibly just one screen). Your center screen could push more onto that stack. Then a subsequent sideMenu "navigation" would set a new stack (again, possibly just a single screen) to replace the center view.

Please help me to switch two screens using setStackRoot

The given below structure is my project navigation. Then I want to switch from _tab page_ to a _profile page_. how can I set setStackRoot

Navigation.setRoot({
      root: {
        sideMenu: {
          left: {
            component: {
              name: 'DrawerScreen',
            },
          },
          center: {
            id: 'MY_STACK',
            bottomTabs: {
              children: [{
                stack: {
                  children: [{
                    component: {
                      name: 'HomeScreen',
                    }
                  }],
                  options: {
                    bottomTab: {
                      text: 'Home'
                    }
                  }
                }
              },{
                stack: {
                  children: [{
                    component: {
                      name: 'TabSettingsScreen',
                      passProps: {
                        text: 'This is tab 1'
                      }
                    }
                  }],
                  options: {
                    bottomTab: {
                      text: 'Setings'
                    }
                  }
                }
              }]
            }
          },
        },
      },
    })

Your center screen MY_STACK is bottomTabs not a stack. You can only use setStackRoot on stacks, not tabs. You鈥檒l need to wrap your bottomTabs in a Stack.

@rgoldiez Thanks, can you give an example for this.

@rgoldiez thank you for the examples!
I'm still having a hard time to figure out how to push and pop screens to the center stack from sideMenu.

Navigation.push(CENTER_STACK_ID, {options})

works for me but after one

Navigation.pop(CENTER_STACK_ID)

the push stops working

@paalex - Not really sure. We moved away from RNN because of too many unresolved issues on V2.

@rgoldiez thanks.

I managed to solve the pop issue now using:

      Navigation.pop(this.activeNavigationComponent.componentId);

and also

    Navigation.events().registerComponentDidAppearListener(({ componentId, componentName }) => {
      this.activeNavigationComponent = { componentId, componentName };
    });

But you have to make sure you close the sideMenu before doing pop

      Navigation.mergeOptions(Constants.appStacks.mainStack, { sideMenu: { left: { visible: false }, right: { visible: false }}});

Sort of a workaround 馃憥

@rgoldiez what framework are you using now? I have followed the sideMenu to the teeth and still have no luck implementing it. I feel like something is broken.

@paalex would you have updated code for your sideMenu I can look at?(that works)

@max77p - we switched to react navigation

Any Updates?

For anyone with a bottom tab as the center component in a sidemenu root, the following was helpful to me after clicking a sidemenu option:

Navigation.showModal({
    stack: {
      children: [{
        component: {
          name: 'Profile', <-- pass the screen you want to nav here
          passProps: {
            text: 'stack with one child'
          },
          options: {
            topBar: {
              title: {
                text: 'Profile'
              },
              leftButtons: otherLeftButtons // <-- define your left button option as you'll need it to return to previous screen 
// since pop wont work. Also, add a navigationButtonPressed({...eventoptions}) event to the screen you want to nav to and define what happens
// when you click the back button (Navigation.dismissModal(componentId)
            }
          }
        }
      }]
    }
});

I hope the above helps? I had issues understanding the lib, so I open-sourced my pet project with RNN and other new libs I am currently exploring to help others. Find it here: https://github.com/nwaughachukwuma/eventsmag.

Was this page helpful?
0 / 5 - 0 ratings