React Navigation tutorial (0.60) — createMaterialTopTabNavigator basic implementation

Alex
7 min readAug 18, 2019

Hi there, it has been a while since I have written an article and thought while I’m listening to 90s house music and drinking Coca cola I would concoct a tutorial for one of my favourite libraries within the React Native world, React Navigation. The tutorial will involve creating a project from scratch and implementing a very basic material design top tab navigator, so lets get to it.

The first thing to do is to find a place on your computer to create the project, it could be your desktop or Downloads etc, then in the terminal or command line navigate to this folder and enter the command below.

react-native init MyAmazingProject

This will then create all the necessary files for your React-Native project.

NOTE: I am using React Native version 0.60 (So the latest version of React Native as of the date this article was created) so in the new version of React-Native packages we install automatically link and i’ll go through how to properly integrate React-Navigation into your project later in the tutorial.

After your project has finished creating itself in the command enter the below command

npm install react-navigation react-native-gesture-handler react-native-reanimated

react-navigation — solution for navigating around your react native project

react-native-gesture-handler — With this library gestures are no longer controlled by the JS responder system, but instead are recognized and tracked in the UI thread. (Got this straight from the RNGH github repository)

react-native-reanimated — Improved version of the Animated library for React-Native

The next step is to change directory to your “ios” folder using

cd ios

and then run the command

pod install

The reason for this is that a cool new feature of React-Native 0.60 is that it ships directly with CocoaPods so we need to ensure the packages are linked by installing them as pods as well. This installation will take a minute or so.

The next step is to add minor modifications to the “MainActivity.Java” file in your android file located somewhere in the below (Where obviously where it says “MyProjectName” it will be the name you gave the project when you ran “react-native init”.

MyProjectName/android/app/src/main/java/com/topswipemenu/MainActivity.java

You will need to add these 3 import statements at the top of the “MainActivity.Java” file

import com.facebook.react.ReactActivityDelegate;import com.facebook.react.ReactRootView;import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;

In addition, you will need to add the below function one or two lines after the function “getMainComponentName” to complete the installation of “react-native-gesture-handler” on Android.

@Overrideprotected ReactActivityDelegate createReactActivityDelegate() {return new ReactActivityDelegate(this, getMainComponentName()) {@Overrideprotected ReactRootView createRootView() {return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}

Now run your project using either “react-native run-ios” or “react-native run-android” and no errors should appear.

If all is well we can now begin to implement a basic material design swiper menu on React-Native, the first thing to do is to import 2 objects from “react-navigation”.

import {createAppContainer,createMaterialTopTabNavigator} from 'react-navigation';

createMaterialTopTabNavigator- is the tab bar that we will be showing to the user and allows a butt-load of customization such as active/inactive colour, lazy loading and swiping capabilities!

createAppContainer — Responsible for linking your root (top-level)navigator to the apps environment, we pass in the “createMaterialTopTabNavigator” as an argument to this function as you will see later.

Furthermore, get rid of the default cr*p in your “app” function and replace it with something basic like the below. So we have a container view with some basic styling and a text tag.

const App = () => {return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
};

The next step is to create a const variable with a name like “AppContainer” and set it equal to the “createMaterialTopTabNavigator” that takes an object as an argument, this is called the “route configuration object” and it is used to map a “route name” which is the key to a “route config” which is the React component. Next, add the default page with the key “Home” that is an object containing the necessary key “screen” and its value “App” which will be a React component. In addition I have added some basic styling for the navigator including a background colour and an active tint colour so when that route is active on the screen the text will turn orange a screenshot of this is below.

const AppNavigator = createMaterialTopTabNavigator({Home:{screen:App,}},{tabBarOptions:{style:{marginTop:50,backgroundColor:'black'},activeTintColor:'orange',
},
}
)

Don’t worry if your app doesn’t look exactly like this as we haven’t created the second page yet, so the next thing to do is to create a folder in the root of your project called “components” and create a Javascript file in this folder called “Test” and insert the below code into this file.

import React from 'react';import {Text,View,StyleSheet} from 'react-native';class Test extends React.Component{render(){return(<View><Text>Test file</Text></View>)}
}
export default Test;

After you have created this file you will need to import this component into the “App.js” file with the below code.

import Test from './components/Test';

As you can see we are importing the class “Test” from the javascript file “Test.js”, furthermore, we now need to add another route to our “route configuration object” so we can see the “Test” page on the top bar navigator, to do this add the code.

TestPage:{screen:Test}

So now our full route configuration object should look like this.

const AppNavigator = createMaterialTopTabNavigator({Home:{screen:App,},TestPage:{screen:Test}},{tabBarOptions:{style:{marginTop:50,backgroundColor:'black'},activeTintColor:'orange',},
}
)

After adding this reload or restart your project and you should now see 2 routes on the navigator like the screenshot below.

However, I wanted to go over a few customization options that React-Navigation offers, as you can see our second screen has the title “TESTPAGE”, with it being all capitals and one word it doesn’t look very attractive, we can change with a few lines of code though!

The first thing to do is to add the “upperCaseLabel:false” property inside of the “tabBarOptions” object, as React-Navigation sets the label to be uppercase by default so we need to set it to false to disable this. So your “tabBarOptions” should now look like the below.

tabBarOptions:{style:{marginTop:50,backgroundColor:'black'},activeTintColor:'orange',upperCaseLabel:false},

Now we have solved the case issue we now want to edit the actual label on the route, to do this go back to the “Test.js” file and define a static variable called “navigationOptions” and set it equal to an empty object like the below.

static navigationOptions = {}

“navigationOptions” is an object which can be used to customise various aspects of specific components and in our case we want to change the title of the navigation route to something more user friendly, we can set the title of the navigation route using either “title” or “tabBarLabel” as the key. The difference between the two being that if “tabBarLabel” is not used then the value will default to “title”.

So your “navigationOptions” should now look like this

static navigationOptions = {
title:'My test page!'
}

Note: You don’t have to go to the actual javascript file to add “navigationOptions”, you can do this directly inside the “route config object”, however, Ilike to do it in a separate file to avoid the code potentially becoming oversaturated, below is an example of how you can implement “navigationOptions” in the “route config object”.

TestPage:{screen:Test,navigationOptions:()=>({title:'my test page'})}

Also, with the navigationOptions object you can enter custom click events for every route, to do this you need to add the key “tabBarOnPress” after the “title” key with 2 parameters “navigation” which is a navigation prop for the screen if you need to navigate to another screen for some reason, in addition, the second is “defaultHandler” which is the default handler for the on press event.

tabBarOnPress:({navigation,defaultHandler})=>{alert("you clicked on test page route!")}

A few good use cases for “tabBarOnPress” is to prevent the user from going to the route based on specific conditions, handle double taps on the route and resetting the state, so now the “route config object” should look like the below.

const AppNavigator = createMaterialTopTabNavigator({Home:{screen:App,},TestPage:{screen:Test,navigationOptions:()=>({title:'my test page',tabBarOnPress:({navigation,defaultHandler})=>{alert(navigation)}})}},{tabBarOptions:{style:{marginTop:50,backgroundColor:'black'},activeTintColor:'orange',upperCaseLabel:false},})

Other useful properties:

swipeEnabled — Enabled by default but if you don’t want the user to be able to swipe to the route you can set this to false

animationEnabled — Enabled by default but if you don’t want the user to be able view the animation in between switching routes then you can set this to false.

tabBarPosition — You can set the position of the bar to be at the top or bottom of the screen, the default is “top”

lazy — Default value of this is set to false, if this is set to “true” the tabs are rendered to the screen only when they are made active, when this is set to false all the tabs are rendered to the screen immediately.

Hopefully you have learnt something from this article I know I have learnt a lot from researching React-Navigation and its amazing capabilities!

If you have any criticisms or constructive feedback on how I can improve my articles or the grammar of them then feel free to tell me as I am always looking to improve!

--

--