React Native Navigation
Traditionally, the de-facto solutions for multiplatform mobile apps were based on hybrid frameworks like Ionic, which uses web technologies (HTML, CSS, JS) to write and render the app on any device. It’s a great framework, it makes its best in order to reproduce a near-native behavior to provide the best user experience, but sometimes our projects require the real look and feel of an iOS and Android app.
In the last year, we’ve been working on some web projects based on React, the well-known web framework made by Facebook, and it was a satisfying experience. This way, we decided to research on the other big-boy Facebook’s framework: React Native. It basically let us build native apps based on JavaScript and React. Cool, right?
It today’s post we will show a brief example of a navigation implementation with React Native, and how it reproduce a real look and feel native navigation experience on both Android and iOS.
In order to implement the navigation, we’re gonna use a community solution recommended by Facebook: React Navigation. React Navigation provides many navigation styles like stack, tabs and drawer with a real native feeling. Now we’re gonna present a simple example of a stack navigation.
Before starting we must set up all the development environment of React Native and create a project as explained here.
Once the project is created, we start defining the app navigation using the Stack Navigator. The Stack Navigator implements transitions betweens screens, where each screen is pushed in the top of the stack. In Android apps, the screens fade in from the bottom, and in iOS apps the screens slide in from the right.
AppNavigation.js:
import React from 'react';
import { StackNavigator } from 'react-navigation'
import FirstScreen from './FirstScreen'
import SecondScreen from './SecondScreen'
const AppNavigation = StackNavigator({
First: {
screen: FirstScreen,
navigationOptions: {
title: 'First Screen',
}
},
Second: {
screen: SecondScreen,
navigationOptions: {
title: 'Second Screen',
}
}
})
export default AppNavigation
Here you will notice that there are two screens in the navigator: FirstScreen
and SecondScreen
, which are just two regular React components. Also, you should notice the First
and Second
keys on the object received by the StackNavigator
constructor. These keys define the names of the screens in order to perform transitions, as we’re gonna see later. Finally, the navigationOptions
inside each screen object defines many properties for the screen, such as header color and title. You can find every customizable property you can define for the screen here.
FirstScreen.js:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
Button
} from 'react-native';
export default class FirstScreen extends Component {
render() {
const { navigate } = this.props.navigation;
return (
Welcome to the Native Navigation Example!
);
}
}
const styles = StyleSheet.create({
title: {
fontSize: 18
},
container: {
alignItems: 'center',
paddingTop: 50
}
});
Lets take a look at this. First, you will notice there is a navigation
prop in the component with a navigate
function inside. This prop is provided by the navigator in order to make transitions from one screen to the other, and receives as a parameter the name of the screen defined in the navigator. Once the button is pressed, we execute the prop in order to make the transition.
SecondScreen.js:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
} from 'react-native';
export default class SecondScreen extends Component {
render() {
return (
This is the second screen!
);
}
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
paddingTop: 50
}
});
In order to run this example, we must set the AppNavigator
component as the entry point of both Android and iOS apps, so the following code must be placed inside both index.android.js
and index.ios.js
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import AppNavigation from './app/AppNavigation'
export default class NativeNavigationExample extends Component {
render() {
return
}
}
AppRegistry.registerComponent('NativeNavigationExample', () => NativeNavigationExample);
Lets take a look the result. In order to run the apps, we must use the react-native
CLI.
To run the iOS app: react-native run-ios
To run the Android app: react-native run-android
iOS result:

Android result:

As you can see, both navigations follows their respectives native look and feel.
Passing parameters between screens
Now, can we pass some data from one screen to the next one in the stack? Yes, we can do this and very easily.
In order to do this, we’re gonna add a new screen to the navigation stack, that will render its content based on a parameter received from the previous screen.
ThirdScreen.js:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
Image,
} from 'react-native';
const octobot = require('./images/full_pulpo.png')
export default class ThirdScreen extends Component {
render() {
const { navigate } = this.props.navigation;
const { params } = this.props.navigation.state;
return (
This is the third screen!
{ params.showOctobot && }
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
padding: 30,
alignItems: 'center',
}
});
Now, lets make some changes on the SecondScreen
component in order to implement the functionality to provide data as parameters to the new screen.
SecondScreen.js:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
Button,
Switch
} from 'react-native';
export default class SecondScreen extends Component {
state = {
showOctobot: false
}
render() {
const { params } = this.props.navigation.state;
const { navigate } = this.props.navigation;
return (
Show Octobot?
this.setState({showOctobot: value})}
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
paddingTop: 50
}
});
As you can see, the navigate
functions also accepts a JavaScript object as data parameter to the next screen.
Finally, we must add the new screen to the stack navigator like we did previously:
const AppNavigation = StackNavigator({
First: {
screen: FirstScreen,
navigationOptions: {
title: 'First Screen',
}
},
Second: {
screen: SecondScreen,
navigationOptions: {
title: 'Second Screen',
}
},
Third: {
screen: ThirdScreen,
navigationOptions: {
title: 'Third Screen'
}
}
})
Lets run again the two apps with the react-native
CLI and see the results.
iOS result:

Android result:

As you can see, implementing a native navigation and passing parameters from one screen to each other is very straightforward.
The full example can be found here. Check it out!
See related posts

Applying SOLID Principles in React
The SOLID principles are specifically applied in software development, and in this blog post we talk about using them with React.

How We Boosted Our Testing Efficiency as a Team
A dev team organizes a workshop for discussing how to improve testing efficiency with React Testing Library. Read the blog post to find their good practices.