React Navigation Drawer Tutorial

How to add a drawer to your React Native app using react-navigation — Part 1

Gant Laborde
Red Shift

PLEASE NOTE: This was written in react-navigation 1.x. Things have changed and I will need to updated the blog post for 2.x

I’m sure you’ve read the docs on the react-navigation drawer, thus why you’re here. Navigation sounds simple, but it never is.

React Native has a short yet sordid history with navigation. Personally, I’ve had to solve the drawer problem three times over the past two years. Alas, we now ask, “Will react-navigation stand the test of time?” I sure as hell hope so!

I’m going to build a real-world drawer navigation system, and if your needs are simpler than what I’m saying here, then GOOD! This is still the blog for you to understand react-navigation drawer.

I’ve broken this process into four steps. We’ll cover Part One in this post.

Part One:

Step 1:
• Add react-navigation
• Hook it up to Redux

Step 2:
• Identify drawer behavior for your app
• Add default react-navigation drawer
• Add drawer menu button (hamburger button)

Part Two:

Step 3:
• Customizing drawer labels
• Fix drawer toggle
• Fix login animation
• Stop gestures from breaking login flow

Step 4:
• Make your own custom drawer component
• Add logout feature to drawer

After these four steps we will have a drawer that is only accessible after login, via the way we organized our navigation stack.

Step 1: Add a basic react-navigation

There are MANY ways to do this. My personal favorite way to add react-navigation to my project is to make it have an optional opt-in to Redux. I like to do this by having my routes sit in one file AppNavigation and keep the Redux logic in a separate file. This is how we initialize projects with our boilerplate. That second file is named ReduxNavigation (it uses AppNavigation for the routes.) Now if I want Redux, I import one that is connected, and if I don’t, I import the other!

The most basic navigation would be a simple stack with a single route. Something like this:

Breaking this down is simple: Import screen, make a route, configure it.

Wrapping this in Redux is also simple: It is NOT essential to this blog post. So if you would like to skip connecting your navigation to Redux, that’s fine.

I’d like to cover some of the benefits of using Redux for your navigation with a drawer, so for those of you looking to have a well-rounded solution; follow along. We wire in to Redux by connecting a component that wraps AppNavigation and also making a space for Redux data in our reducers.

There we go! Now our changes to AppNavigation will be piped through our new Reducer and we can watch those dispatches with something like redux-logger or Reactotron.

This concludes Step 1! Review the full code for Step 1 here: https://github.com/GantMan/drawer-example/tree/step1

Step 2: Don’t Make a Junk Drawer

You might be excited to add the drawer, but due to the construct of react-navigation, you should really take a moment to consider your workflow. Before rushing into this setup consider the following first:

1. Will my drawer be available all the time?

Some apps will load the hamburger icon for logged in users, and no menu for users who have yet to log in, while other apps have the drawer constantly.

In this blog example, we’ll go with the “no menu until login” option, because it’s more complicated.

2. Will my drawer navigate with stacks in a tab-like behavior?

To explain this, let’s pretend we’re like Netflix. If I use the drawer to go to “Classic Films”, and then I select from that screen “From the 90's”. This second screen is part of the “Classic Films” stack. If I now quickly jump to the settings, and then navigate back to “Classic Films” from the drawer, it makes sense that it returns to the same spot in the stack, the “From the 90’s” screen. That is tab-like behavior.

In this blog example, we’ll go with “yes, each menu item is a stack”, because it adds structure to our app that can be appreciated, and though more structure means more management, it clearly identifies how we expect navigation to work.

Adding our Desired Drawer Stack

Now to modify our stack we simply edit our AppNavigation file.

Identify Desired Navigation Structure:

  1. No hamburger/drawer for login screens
  2. Once logged in, show drawer
  3. Each drawer item is a stack

Two main stacks

Since the drawer isn’t always visible, we’ll make 2 stacks. One for login/signup/forgot password, and the other for everything that will be accessible via the drawer.

Great! So now it’s broken into two parts. The first part is everything that shouldn’t see our drawer at all. This will simply be it’s own stack.

For emphasis, I’ve made the header red. This way we can have a high contrast from logged out to logged in.

the header code renders like this.

Now you may say, “let’s make that other stack the drawer, right?” But it’s very likely that all our other screens will share a logged in header. This is where we’ll place the permanent hamburger button. Instead of jumping directly into the drawer, let’s wrap everything in another stack that we can style.

A quick note on the shared header stack:

It’s worth noting that doing it this way with the shared header stack (having the header live in the stack that owns the drawer, instead of having the header inside the drawer’s route stacks), means that the drawer will be under the header when rendered. Make sure this is is the desired effect. If not, you’ll need to configure your header on all stacks below the drawer instead.

There we go! Our logged in header will be purple! Navigating to these screens will obviously be beyond our login barrier!

Purple header for screens of a logged in user

Lastly, we can now add our screen stacks to the DrawerNavigator. This is as simple as our primary nav was:

TADAAAAA! 🎉 — Technically, it’s there and ready to go for your logged in stack screens!

You have to access it via gesture, which is not user-friendly, but it’s there!!!

Drawer accessible via gestures

Final touch: Add a menu button to open the drawer

Obviously you want to be able to click on something to open your drawer. That gesture solution isn’t very clear. Fortunately, we already have a place to add this button, and that’s our logged in stack. Add this to your navigationOptions of the stack that contains the drawer.

headerLeft: <Text onPress={() => 
navigation.navigate('DrawerOpen')}>Menu</Text>

That’s the simplest way to do it, but since our bar is dark I added a style to switch the text to white.

Clicking on this new Text element will open the new drawer!

Drawer opens perfectly

This concludes Step 2! Review the full code for Step 2 here: https://github.com/GantMan/drawer-example/tree/step2

We have react-navigation installed and our drawer in place, but it leaves a lot to be desired. We’ll need to add some customizations, not only to the styling, but to the default behaviors of our drawer. Here’s part two!

Interested in learning how to bring AI and Machine Learning to web with TensorFlow.js?

JavaScript lets you create front-end websites that can leverage the power of AI directly on the browser. Learn from scratch with this book.

Reserve your copy of Learning Tensorflow.js on Amazon

Blog Credits:

Part Two: Finishing the Drawer

Though this feels like it’s done, there are quite a few gotchas. We’ll sharpen up our code in the next installment. Follow on Medium to make sure you catch it!

🎉 About Gant

View technical tweets and puns with @GantLaborde on Twitter, or follow him on Medium and GitHub. You can see where he’s speaking next on http://GantLaborde.com/

Gant Laborde is Chief Technology Strategist at Infinite Red, published author, adjunct professor, world-wide public speaker, and mad-scientist in training. Read the writings of Gant and his co-workers in our Red Shift publication or invite him to speak at your next conference.

Responses (31)

What are your thoughts?