React Native Navigation V2 is Here!

Building a simple app navigation using React Native Navigation V2

React Native Navigation v2 is finally here with some great improvements, like a new architecture and API, and a couple of exciting new features:

If you are already using React Native Navigation V1, this tutorial gives you a quick glimpse of the new API and, hopefully helps you you to reason your decision of moving to V2.

If you are new toReact Native Navigation (RNN), you can start with V2 right away. As opposed to other popular JS navigation solutions for react-native, RNN is a 100% native navigation solution with a simple cross-platform JS API. This tutorial helps you to learn the basics and feel more comfortable diving into the more complex features and API.

What we are going to build

We are going to build the skeleton of a very simple blog app. Consider the following blog app:

The Full app gif
  • We have a list of posts.
  • Pressing on a post will push a screen with the post content.
  • From the View Post screen, we can delete the post and go back to the posts list.
  • From the list, we also have an option to open a modal for adding posts.
  • From the Add Post screen, we can cancel or save and go back to the posts list.

Here is the outline of what we are going to build:

The skeleton off the app that we are going to build


Preliminaries: Before you dive into this tutorial, you need to understand the basics of React Native. You can use the official React Native Getting Started guide.

If your project already uses React Native Navigation V1, the best option for migrating your code base to V2 will be to use react-native-navigation-v1-v2-adapter. For easier migration, the adapter will still work with V1 api and will display, using console.warn, the appropriate v2 api which you should use instead.

If you are starting from a clean sheet, you have two options:

  1. Follow the Installation guide from the official v2 docs.
  2. Using the following React Native Init project that comes with RNN v2. Just follow the steps in the README to run the project.

We’ll use the latter choice in our further samples, so it is the best option to pick if you wish to follow along with this tutorial. Considering that you have chosen option 2, your app looks like this:

React Native Init project — option 2

Adding the Screens

let’s create three screens (PostsList, ViewPost and AddPost). Each screen will currently be a very basic component that looks like this:

Bear in mind that I’m using react-native-ui-lib for a little bit of help with styling. In addition to lots of great components that this library offers, it also wraps lots of react-native components and adds additional functionalities to them, like using Modifiers and predefined styles. These are the flex,center ,bg-blue70 and text40 props in the code above.

We will update the src/screens file to register the new screens that we just created. Every screen component in our app must be registered with a unique name before we are able to use it. Here is what our screens.js file should look like:

From our index.js file, we call registerScreens and initialise the app layout that we want via the setRoot command. The possibilities of the layout API are almost endless and you can compose almost any arbitrary native layout. You can check out all of the layout types here. We will start with the most simple layout which is based on one stack with one component, our PostsList screen. Here is what theindex.js file looks like:

We have set the root using one stack with the PostsList component and the top bar title provided in the Options object. You can check the complete Options object format here.

After refreshing the app, you get the the bluePostsList screen.

All the changes described in this section are provided in this commit.
Adding our screens

Pushing the First Screen

So now we want to enable the following behavior: after user clicks on the text, the app pushes the ViewPost screen. Later on it will be very easy to attach the same function to a list item instead of the text. To push a new screen into this screen’s navigation stack, we will use Navigation.push. In the new API this method expects to receive the current componentId which can be found in props.componentID . So in PostsList.js we create a pushViewPostScreen function and attach it to the onPress event of the Text.

Two things in the code above that we didn’t cover are:

passProp(line 23) - We can pass props to the screen that we are pushing.

options(line 26)- We can style the navigator appearance and behavior by passing an Options object. This object can be declared in two different ways. You can declared the object dynamically when adding a screen to the layout hierarch, like we did in the code above. You can also define the object by setting static get options() on the screen component. This declaration is static and should be done for every screen. In the next section, we will explore this option.

After refreshing the app, you are now able to push thee ViewPost screen by clicking the text.

All the steps from this section can be viewed in this commit.

Adding the “Add” Button

On the PostsLists screen, we want to have an “Add” button that will open the AddPost screen as a modal. Buttons are part of the Options object. We will declare the button in the PostsList screen statically. Top bar buttons have multiple options for customization, but we will declare a very simple button with a title and id.

We want to component to handle the button click. We will need to do 2 things:

  1. Add events().bindComponent(this)to the constructor.
  2. When a top bar button press event is triggered, the app calls the navigationButtonPressed , so we will implement it with the pressed button id.

Now we have an Add button and whenever we press it, we get an alert with the buttonId (in our example it is addPost).

Now, we need to handle the press event and show the AddPost screen as a modal, To show a screen as a modal we will use Navigation.showModal.

All the steps from this section can be viewed in this commit.

Adding Buttons to the AddPost Screen

In the same way that we added the AddButton, we will now add the Cancel and Save buttons to the Top bar of the AddPost screen. Whenever the Cancel button is clicked, we use Navigation.dismissModal to dismiss the modal and go back to the PostsList screen.

But we are not quite done yet. In the full app gif at the top of the tutorial, the Save button should be disabled until the user starts typing something in the TextInput. To disable the button, we can simply add enabled: false in the button option.

But how do we set styles dynamically? Navigation.mergeOptions to the rescue! We can pass any Options object in the mergeOptions method that dynamically changes a screen style. These options are merged with the existing Options object. So this is what theAddPost screen looks like now:

We are Almost Done

The app navigation skeleton is almost ready and I will leave it to you to implement the remaining buttons press events:

Delete- Use Navigation.pop to pop the ViewPost screen from the stack and reveal the PostsList screen underneath.

Save- Dismiss the modal in the same way the Cancel button does.

Quick Recap

So what have we learned in this tutorial?

You can view the full project in the react-native-simple blog repository

What’s Next

In the future, I’m also planning to release a tutorial that will cover the process of building the complete and functional blog app including state management, working with REST api, styling, e2e tests and more, so stay tuned 😻

React Native Navigation Logo