React Native - Navigation



In this chapter we will show you how to set up navigation in React Native app.

Keep close attention since we will refactor lot of the code but we will show you interesting features.

All previous chapters used MyContainerComponent and MyPresentationalComponent. We did this to get comfortable with separation of logic and view.

Now that you grasped the concept we will use real life examples in our following chapters.

Step 1 - Create Files and Folders

We will explain our files and folders in following list −

  • Router.js − This is our Router component. We will place it inside src/components folder.

  • home − Home page folder. Path to this folder is src/components/home. We will create two components here HomeContainer.js and HomeButton.js

  • about − About page folder. Path to this folder is src/components/about. We will have AboutContainer.js and AboutButton.js inside.

Navigation Structure

Step 2 - Router

There is a lot of things going on in example below.

  • Navigator − This element handles routing. We are setting initialRoute, renderScene and navigatorBar. We will go through these props below.

  • initialRoute − We are setting which route will be rendered first when we start the app. This is just an object where we are setting name (used for routing) and title (used for setting title).

  • renderScene − This is function for calculating routes. We are using route.name for this. If you check initialRoute you will see that name: 'Home' is the same as route.name == 'Home' in renderScene. This is how the app knows that initial route is Home.

    We will also pass navigator and ...route.passProps so we can access everything inside rendered component.

  • NavigationBar − We are using NavigationBarRouteMapper prop so we can add title and buttons for navigation bar. Left button will be used as a back button while right button will only be present if route.openMenu exists. You will see more on this inside Home component.

Example

import React, { Component } from 'react'

import {
   StyleSheet,
   Text,
   Navigator,
   TouchableOpacity
} from 'react-native'

import AboutContainer from './about/AboutContainer'
import HomeContainer from './home/HomeContainer'

export default class Router extends Component {
   constructor() {
      super()
   }
   render() {
      return (
         <Navigator
            initialRoute = {{ name: 'Home', title: 'Home' }}
            renderScene = { this.renderScene }
            navigationBar = {
               <Navigator.NavigationBar
                  style = { styles.navigationBar }
                  routeMapper = { NavigationBarRouteMapper } />
            }
         />
      );
   }
   renderScene(route, navigator) {
      if(route.name == 'Home') {
         return (
            <HomeContainer
               navigator = {navigator}
               {...route.passProps} 
            />
         )
      }
      if(route.name == 'About') {
         return (
            <AboutContainer
               navigator = {navigator}
               {...route.passProps} 
            />
         )
      }
   }
}

var NavigationBarRouteMapper = {
   LeftButton(route, navigator, index, navState) {
      if(index > 0) {
         return (
            <TouchableOpacity
               onPress = {() => { if (index > 0) { navigator.pop() } }}>
               <Text style={ styles.leftButton }>
                  Back
               </Text>
            </TouchableOpacity>
         )
      }
      else { return null }
   },
   RightButton(route, navigator, index, navState) {
      if (route.openMenu) return (
         <TouchableOpacity
            onPress = { () => route.openMenu() }>
            <Text style = { styles.rightButton }>
               { route.rightText || 'Menu' }
            </Text>
         </TouchableOpacity>
      )
   },
   Title(route, navigator, index, navState) {
      return (
         <Text style = { styles.title }>
            {route.title}
         </Text>
      )
   }
};

const styles = StyleSheet.create({
   navigationBar: {
      backgroundColor: 'blue',
   },
   leftButton: {
      color: '#ffffff',
      margin: 10,
      fontSize: 17,
   },
   title: {
      paddingVertical: 10,
      color: '#ffffff',
      justifyContent: 'center',
      fontSize: 18
   },
   rightButton: {
      color: 'white',
      margin: 10,
      fontSize: 16
   }
})

Step 3 - Home Components

This is our container component. We are passing goToAbout prop to HomeButton. Notice openMenu: this.openMenu inside push function. This will enable Menu button on About screen.

src/components/home/HomeContainer.jss

Example

import React, { Component } from 'react'
import {
   View
} from 'react-native'
import HomeButton from './HomeButton'

export default class HomeContainer extends Component {
   constructor() {
      super()
   }
   render() {
      return (
         <View>
            <HomeButton goToAbout = {this.goToAbout}/>
         </View>
      )
   }
   openMenu = () =>{
      alert("Menu button pressed!")
   }
   goToAbout = () => {
      this.props.navigator.push({
         name: 'About',
         title: 'About',
         openMenu: this.openMenu
      });
   }
}

HomeButton is presentational component. It handles styling and calls goToAbout function passed as a prop from HomeContainer.

src/components/home/HomeButton.js

Example

import React, { Component } from 'react'
import {
   View,
   Text,
   TouchableOpacity,
   StyleSheet
} from 'react-native'

export default HomeButton = (props) => {
   return (
      <View style = {styles.container}>
         <TouchableOpacity
            style = {styles.button}
            onPress = {props.goToAbout}>
            <Text>
               Go To About
            </Text>
         </TouchableOpacity>
      </View>
   )
}

const styles = StyleSheet.create ({
   container: {
      marginTop: 100,
      flexDirection: 'column',
      justifyContent: 'center',
      alignItems: 'center'
   },
   button: {
      borderWidth: 1,
      padding: 10,
      borderColor: 'black'
   }
})

Step 4 - About Component

This is just an empty component used for About screen.

src/components/about/AboutContainer.js

Example

import React, { Component } from 'react'
import {
   View,
} from 'react-native'

export default class AboutContainer extends Component {
   constructor() {
      super()
   }
   render() {
      return (
         <View>
         
         </View>
      )
   }
}

Step 5 - Connect Router

To be able to use router inside our app, we will place it inside index.ios.js and index.android.js

index.ios.js and index.android.js

Example

import React, { Component } from 'react'
import {
   AppRegistry,
   View
} from 'react-native'
import Router from './src/components/Router'

class reactTutorialApp extends Component {
   render() {
      return (
         <Router />
      )
   }
}

AppRegistry.registerComponent('reactTutorialApp', () => reactTutorialApp)

Now we can run the app. Home screen will be shown.

Output

Navigation Home

We can press the button to open About screen.

Notice that Back and Menu button appear inside navigation bar.

Navigation About
Advertisements