Navigation in React Native

Notes on using React Navigation

/Screenshot_2019-07-24_12-07-38-react-navigation.png

React Native navigation is largely analogous to the concept of routing in React.js Web development, although it does work a bit differently, being that URLs are not an inherent part of the mobile application experience.

Some (older) materials recommend wix react native navigation for implementing RN navigation. This was preferred by many developers because the official React Navigation was once notoriously buggy. However, the consensus now seems to be that those issues have mostly been ironed out.

Notes

The reactnavigation.org docs are a great reference. It is even possible to conveniently experiment with navigation features in an expo simulator.

There are many types of navigation available.
- Stack
- Switch
- AnimatedSwitch
- Drawer
- Tab
- Stack
- MaterialStack
- MaterialTopTab

The Screen

An fundamental concept in React Native navigation is the screen. A screen is essentially a component in the main body of an app that is rendered selectively, like a route or a view.

Like in React Router, React Navigation is implemented though middleware. A typical setup would include an App.js file that exports an AppNavigator, which might look something like this:

const AppNavigator = createStackNavigator({
  Home: { 
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  },{
    initialRouteName: 'Home'
});

export default createAppContainer(AppNavigator);

Navigation between screens is achieved through the navigation.navigate() function. To accomplish linking between screens, an onPress function like this can be used.

<Button
  title='Go to About'
  onPress={ () => this.props.navigation.navigate('About') }
/>

If you are familiar with React Router, you will probably recognize that this works like history.push(). The navigation element is automatically passed to each screen through props.

  • navigation.goBack()’ – return to last screen

Passing Params

Parameter passing works differently in React Native than web, because URLs are not used. Instead, params are passed to a screen like this:

<Button
  title='Go to stockmarket graph'
  onPress={ () => this.props.navigation.navigate('Stocks', {
      stockName:  'IBM',
      startRange: '1-1-2015',
      endRange:   '6-1-2015'
    })
  }
/>

These parameters than then be recalled from inside that screen using navigation.getParam().

const stockName = this.props.navigation.getParam('stockName')
const startRange = this.props.navigation.getParam('startRange')

A default value can also be added in the case that a particular parameter is not passed in.

const endRange = this.props.navigation.getParam('endRange', 'Present')

Using Navigation Options

static navigationOptions = {
  headerStyle: {
    backgroundColor:'white'
  },
  headerTintColor:'blue'
};

*Note the use of the static keyword.

Set Default Navigation Options

const AppNavigator = createStackNavigator({
  Home: { 
    screen: HomeScreen
  },
  About: {
    screen: AboutScreen
  }
}, {
  initialRouteName: 'Home',
  defaultNavigationOptions: {
    headerStyle: {
      backgroundColor:'white'
    },
    headerTintColor:'blue'
  }
});

Set Navigation Options directly on the Route Config

const AppNavigator = createStackNavigator({
  Home: { 
    screen: HomeScreen,
    navigationOptions: ({navigation}) => ({
      title: `${navigation.state.params.name}'s Profile`
    })
  },
  About: {
    screen: AboutScreen
  }
}, {
  initialRouteName: 'Home'
});
  • Note the passing of navigation inside navigationOptions, and function passing state therein.

Stack Navigator

Stack Navigator is one type of navigation. Each type has it’s own set of options. There are many options for the stack navigator. Some of these, like onTransitionStart, allow for callbacks to be used.

Route Configs

Router Option Function
initialRouteName Sets the default screen of the stack. Must match one of the keys in route configs.
initialRouteParams The params for the initial route
initialRouteKey Optional identifier of the initial route
navigationOptions Navigation options for the navigator itself, to configure a parent navigator
defaultNavigationOptions Default navigation options to use for screens
paths A mapping of overrides for the paths set in the route configs
disableKeyboardHandling If true, the keyboard will NOT automatically dismiss when navigating to a new screen. Defaults to false. This is ignored in the web platform.

Visual Options

mode Defines the style for rendering and transitions
card Use the standard iOS and Android screen transitions. This is the default.
modal Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
headerMode Specifies how the header should be rendered
float Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
screen Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
none No header will be rendered.

Bottom Tab Navigator

Another example of a navigation is the Bottom Tab Navigator It has it’s own set of Visual Options

Option Function
initialRouteName The routeName for the initial tab route when first loading.
navigationOptions Navigation options for the navigator itself, to configure a parent navigator
defaultNavigationOptions Default navigation options to use for screens
resetOnBlur Reset the state of any nested navigators when switching away from a screen. Defaults to false.
order Array of routeNames which defines the order of the tabs.
paths Provide a mapping of routeName to path config, which overrides the paths set in the routeConfigs.
backBehavior initialRoute to return to initial tab, order to return to previous tab, history to return to last visited tab, or none.
import { createBottomTabNavigator, BottomTabBar } from 'react-navigation-tabs';

const TabBarComponent = (props) => (<BottomTabBar {...props} />);

const TabScreens = createBottomTabNavigator({
    tabBarComponent: props =>
      <TabBarComponent
        {...props}
        style={{ borderTopColor: '#605F60' }}
      />,
  },
);
const AppNavigator = createBottomTabNavigator({
  Home: HomeScreen,
  Users: UserScreen
}, {
  initialRouteName:'Home',
  order: ['Users','Home'],
  defaultNavigationOptions: ({navigation}) => ({
    tabBarOnPress: ({navigation,defaultHandler}) => {
      if (navigation.state.key === 'Users') {
        navigation.navigate('Users');
      } else {
        defaultHandler();
      }
    }
  })
});

Linking and Combining Navigation Components

const HomeStack = createStackNavigator({
  Home: HomeScreen,
  Users: UserScreen
});

const OtherStack = createStackNavigator({
  Settings: SettingScreen,
  Users: UserScreen
});

const AppNavigator = createDrawerNavigator({
  Home: HomeStack,
  Settings: OtherStack
});