React Navigation (without Redux)

StackNavigator for React Native.

Building native apps with React Native is real fun. And one of the things that makes it more fun is trying to understand the many moving pieces that go in to the whole ecosystem. Trying to navigate through different screens through your app, I’d say is one such piece. There are a lot of options out there for bringing in “navigation” to your app. But most of them fail to cover the patch of whether it is safe to be put to production. Until recently, there was no specific library recommended by React Native as a go to option for standardized navigation experience. Now the go to library for navigation is React Navigation.

In this article I’ll be going over the most common form of navigation employed in the apps “Stack Navigator”. First part is going to be the “non redux way” and the second is going to be the “redux way”.

Essentially the behavior we are trying to achieve with a StackNavigator looks something like this:

  1. Click a button on Page 1. (page 1 gets pushed to 1 entry below on the stack)
  2. Page 2 slides over page 1 with some data in it. (page 2 is pushed on top of page 1 in the stack)
  3. Click the back button on page 2, page 2 slides out of the screen and page 1 becomes visible again. (page 2 is popped out of the stack and page 1 is now on top of the stack).

Now lets try to understand how the StackNavigator (referred to as SN here) plays a role in helping us achieve this functionality.

The logic that the SN relies on mostly is that all the pages that need to be navigated to either immediately or later down in the Component tree needs to be registered before hand. While registering, you will also have the option to modify the UI of the page navigated to (Eg: show/hide header, title etc). The flow without redux in a tiny app would essentially look something like this:

  1. Routes consists of a list of components (that make a page) that needs to be navigated to.
  2. AppNavigator reads the routes file, maps the routes comment to the route name so the navigator knows what to show upon the “navigation animation” when called.
  3. Page 1 component with navigation props.
  4. A button on Page 1 that when clicked calls navigator with a route name that needs to be navigated to.
  5. Page 2 that is shown on top of page 1 as a result of the above navigation call.

Starting with some boilerplate App component

The routes are defined in a separate route.js file as mentioned in point 1.

In the AppNavigator, the route names are bundled inside the StackNavigator. This is the topmost navigator component with navigation action helpers that are propagated to the default component (in this case Page 1) which it gets from routes.js

Now lets define our Page1Screen mentioned in routes.js. This is essentially just a screen with a clickable button that onPress, navigates to Page2Screen.

Line 24 mentions the action the “button” needs to perform on press. This is essentially calling the navigate helper with the route name on the navigation props that was propagated from the very top (AppNavigator).

What’s really cool about this is if the header option is not set to null, the Back action or the pop functionality comes for free!

As simple as the above flow seems, with more children in the tree, we would essentially be passing around the navigation props throughout (or until the component that calls the navigation). Whats not good about this? Well, the components that don’t need to know anything about the navigation props are being tightly coupled. Once a component in the middle is pulled out, the entire app will break. This is when and why one would consider bringing in Redux. With Redux, the files are decoupled which means the screens can be called from anywhere in the app without having to send down the navigation helpers.

In my next article, I’ll be discussing how Redux can be used to achieve this, what the high level flow looks and of course a working example to help you understand better. Please feel free to post your questions/ opinions/ suggestions. :)

Developer