Handling navigation in react native in a better way

Saurabh Mhatre
CodeClassifiers
Published in
6 min readDec 18, 2016

Handling navigation in react native has been quite an issue for me and my colleagues since juggling from navigator to navigationExperimental then trying reactnative router flux and many routing solutions made our projects a real mess especially while handling back button functionalities for android side.There is always that little performance/experience gap which gets left behind when you compare navigation experience between native apps and JS native apps when your apps are complex and have to display heavy content.

Recently I came across sample movie app created by June Domingo.(You can find the link to try out the app on android from his github page here) and felt that the navigation used by the app was almost close to native app experience.So I decided to give react native navigation from wix a try and write this article simultaneously.

I am going to restrict myself to handle android part in this tutorial and cover ios in later ones when I get time.

Below are the steps to create a basic app boilerplate with react native navigation:

Create a new project :

react-native init projectname

Here my final package.json with all the modules from which you can alter your project’s package.json accordingly:

{
"name": "exampleproject",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"axios": "^0.15.3",
"native-base": "^0.5.18",
"react": "15.4.1",
"react-native-config": "^0.2.0",
"react-native-linear-gradient": "^1.5.15",
"react-native-navigation": "next",
"react-native-scrollable-tab-view": "https://github.com/skv-headless/react-native-scrollable-tab-view.git",
"react-native-sglistview": "^0.3.2",
"react-native-vector-icons": "^3.0.0",
"react-redux": "^4.4.6",
"redux": "^3.6.0",
"redux-logger": "^2.7.4",
"redux-thunk": "^2.1.0"
},
"devDependencies": {
"babel-jest": "17.0.2",
"babel-preset-react-native": "1.9.0",
"jest": "17.0.3",
"react-test-renderer": "15.4.1",
"redux-immutable-state-invariant": "^1.2.4"
},
"jest": {
"preset": "react-native"
}
}

Then run:

npm install && react-native link

Now you need to modify android/ios app files which can be found here:

For android:link

For ios:link

Once finished run the following commands :

For android on linux:

react-native run-android && react-native start

For ios on mac:

react-native run-ios

So lets start structuring your:

Remove all the contents from index.android.js and simply paste the following code:

import App from './src/app';

Create a new src folder in project directory with app.android.js and app.ios.js

Create pages folder within src which will contain all your app pages or screens.Next create a global folder within pages for storing global modules and project folder to store main app pages.Create the other folders as shown:

filesofreactnativenavigation

Design your drawer inside global folder based on your usecase and pages that you need to.

Next register your screens in screens.js as follows:

import { Navigation } from 'react-native-navigation';import Drawer from './pages/global/Drawer';
import Interview from './pages/interview/Interview';
export function registerScreens(store, Provider) {
Navigation.registerComponent('app.Interview', () => Interview, store, Provider);
Navigation.registerComponent('app.Drawer', () => Drawer);
}

Here replace interview with your own page.

Now edit app.android.js in the following manner:

import React from 'react'; // eslint-disable-line
import { Provider } from 'react-redux';
import { Navigation } from 'react-native-navigation';
import { registerScreens } from './screens';
import configureStore from './store/configureStore';
const store = configureStore();registerScreens(store, Provider);const navigatorStyle = {
navBarTextColor: 'white', // change the text color of the title (remembered across pushes)
navBarBackgroundColor: 'black', // change the background color of the nav bar (remembered across pushes)
navBarButtonColor: 'red', // change the button colors of the nav bar (eg. the back button) (remembered across pushes)
navBarHidden: false, // make the nav bar hidden
};
Navigation.startSingleScreenApp({
screen: {
screen: 'app.Interview',
title: 'Home',
navigatorStyle
},
drawer: {
left: {
screen: 'app.Drawer'
}
}
});

You can also have a tabbar based navigation for ios platform by referring to documentation in github page of react-native-navigation.

I have enlisted almost all of available navigator styles below, please use only those that you require.

navBarTextColor: 'white', // change the text color of the title (remembered across pushes)
navBarBackgroundColor: 'black', // change the background color of the nav bar (remembered across pushes)
navBarButtonColor: 'red', // change the button colors of the nav bar (eg. the back button) (remembered across pushes)
navBarHidden: false, // make the nav bar hidden
navBarHideOnScroll: true, // make the nav bar hidden only after the user starts to scroll
navBarTranslucent: false, // make the nav bar semi-translucent, works best with drawUnderNavBar:true
navBarTransparent: false, // make the nav bar transparent, works best with drawUnderNavBar:true
navBarNoBorder: false, // hide the navigation bar bottom border (hair line). Default false
drawUnderNavBar: false, // draw the screen content under the nav bar, works best with navBarTranslucent:true
drawUnderTabBar: false, // draw the screen content under the tab bar (the tab bar is always translucent)
statusBarBlur: false, // blur the area under the status bar, works best with navBarHidden:true
navBarBlur: false, // blur the entire nav bar, works best with drawUnderNavBar:true
tabBarHidden: false, // make the screen content hide the tab bar (remembered across pushes)
statusBarHideWithNavBar: false, // hide the status bar if the nav bar is also hidden, useful for navBarHidden:true
statusBarTextColorScheme: 'dark', //change theme of upper statusbar
tabBarButtonColor: '#ffff00', // change the color of the tab icons and text (also unselected)
tabBarSelectedButtonColor: '#ff9900', // change the color of the selected tab icon and text (only selected)
tabBarBackgroundColor: '#551A8B', //background color of top tab bar
topTabTextColor:'white', //text color of inactive top tab bars
titleBarHideOnScroll:true, //hide title bar on scroll
selectedTopTabTextColor:'white', //text color of selected tab bar displyed above
selectedTopTabIndicatorColor:'red', //color of line diplayed below active tab tab bar
selectedTopTabIndicatorHeight:10 //height of a small line displayed under active tab bar

You can also have tabs at the top using the following code(Especially usefull for android applications) which works similar to react-native-scrollable-tabview:

Navigation.startSingleScreenApp({
screen: {
screen: 'app.TopTabsScreen',
title: 'Interview',
navigatorStyle,
topTabs:[
{
screenId: 'app.Interview',
title: 'Technical',
},
{
screenId: 'app.Interview',
title: 'HR',
},
{
screenId: 'app.Interview',
title: 'Aptitude',
},
]
},
drawer: {
left: {
screen: 'app.Drawer'
}
}
});

Here is screenshot of the final app with three tabs at the top:

reactnativenavigation

You can choose redux to handle data flow in app or not thats entirely upto you.

Couple of reasons why I liked react-native-navigation module by wix was that there is no need to hand button press handles yourself for android.The views that are pushed over the navigation stack are removed by back button press automatically when you use push method provided by the module.

Second useful method is poptoRoot which can be used to empty the stack and return to main page for special circumstances like when user has navigated to many nested views and you want the use to return back to home page on next back button press.You can display/dismiss modals,handle deeplinking easily and there is hidden gem of collapsible tapbar screen that you can use for android specific screens.

Also you don’t need to add external scrollable-tab-view module if your app has tab based navigation since top-tabs/tabbar screen can handle it with ease. Also I found the transition between tabs quite smooth even when I was using dev build so that actually impressed me quite a lot.

In the next tutorial I have covered how to customize drawer,handle on screen navigation and passprops to various screens here.

Check out my other articles on react,redux and reactnative here.

Kindly mention your doubts/recommendations in the comments section and recommend the article to others if you like it.

--

--