1. 程式人生 > >Routing in React Native apps and how to configure your project with React

Routing in React Native apps and how to configure your project with React

Tab Navigator implements a type of navigation that exists in native iOS for many years already. Recently, Android added it to its Material design patterns and native components as well (Bottom Navigation View). Tab Navigator is actually a part of the views it navigates to; it occupies a horizontal part of the screen with tabs (sometimes the tabs are not visible in the design — they look like buttons). Tabs/buttons are usually placed at the bottom of the screen but they can also be placed at the top.

Image 3: Visual example of Tab Navigator

Similarly the Drawer Navigator, is an option that originates in mobile native APIs as well. In this case, the menu screen is a separate view that opens and closes with a drawer-like animation. The menu view contains buttons (links) to the application’s screens.

Image 4: Visual example of Drawer Navigator in Android

If you are using a Tab Navigator or a Draw Navigator there is a chance that you might want to combine it with one or more Stack Navigators. That can be the case when you navigate to a view and from that view you want to navigate to one or more sub-views that are deeper nested in your app’s logic and have nothing to do with the main tab/drawer.

How to configure your app — introduction to navigation flows

Most apps require authentication in some way in order to access user related data and for that process, applications provide a “separate” set of screens that enable that feature.

From this realization a new concept emerges; one that suggests to have two different navigation flows, one for authentication only and another one for the main app. If the application you are developing has a custom register/login section, then you can utilize and implement this idea as shown below.

Authentication Flow

Custom authentication flow is usually consisted of 2 screens: Register and Login. There is no special requirement here; users simply need to be able to access both screens in order to create a new account and also login. For that purpose, we simply need a Stack Navigator and we configure it in our app’s main file (i.e. index.js/App.js) as shown below:

import { createStackNavigator } from 'react-navigation'
// authentication viewsimport Register from './app/views/Register';import Login from './app/views/Login';
const AuthNavigator = createStackNavigator(  {    Login: { screen: Login },    Register: { screen: Register }  },  {    headerMode: 'none'  });

We invoke createStackNavigator methodin order to configure it, which accepts 2 arguments:

  • The 1st argument is an object that contains the mapping of the app’s screens, so that the navigator can recognize them. The keys are the names used from the navigator internally to identify the views while the values is an object that consists of the keyword screen as key and the imported view components as values.
  • The 2nd argument is the configuration object. It is optional and passed only if we want to override the default configuration. In this case we pass headerMode: 'none' in order to remove the default header component passed from the react-navigation library that looks like that:
Image 5: default header of Stack Navigator

Main Application Flow

Main application will make use of one or more of the Navigator structs analyzed before. Let’s see a configuration example of a Drawer Navigator which is combined with Stack Navigators in the cases that there are sub-views besides the main views, as explained before. Our App.js file looks like that

// packagesimport { createDrawerNavigator, createStackNavigator } from 'react-navigation';
// viewsimport Menu from './app/views/Menu';import Home from './app/views/Home';import HomeItemDetails from './app/views/HomeItemDetails';import Calendar from './app/views/Calendar';import EventDetails from './app/views/EventDetails';import Profile from './app/views/Profile';
// create the navigatorsconst HomeStackNavigator = createStackNavigator({  Home: { screen: Home },  HomeItemDetails: { screen: HomeItemDetails }});
const CalendarStackNavigator = createStackNavigator({  Calendar: { screen: Calendar },  EventDetails: { screen: EventDetails }});
// create and configure drawer parent navigator for main appconst AppNavigator = createDrawerNavigator({  Home: { screen: HomeStackNavigator },  Calendar: { screen: CalendarStackNavigator },  Profile: { screen: Profile },}, {  contentComponent: Menu,  drawerWidth: widthPercentageToDP('100%'),  initialRouteName: 'Calendar'});

In this example we configure a Drawer Navigator again by passing 2 arguments; the first one configures the navigation while the latter one configures options of the drawer navigator itself.

Starting with the first object, we see that the Drawer Navigator has 3 views to navigate to: Home, Calendar and Profile. Profile is the simplest one because it only navigates to one main view. Home and Calendar both navigate to a main view from which the app can navigate to sub-views, thus we set a stack navigator for each of them.

Finally we configure Menu view, as the one to be shown when Drawer Navigator is opened and Calendar view as the first to be shown when app is opened and after the user has logged in. Lastly, we set the width of the drawer view to be the 100% of the screen.

Combine the 2 flows

Now we need to provide an overall setup for the 2 flows to work together. Our App.js file looks like that:

import { createSwitchNavigator } from 'react-navigation';
// create switch navigation with authentication flow and main appconst SwitchNavigator = createSwitchNavigator(  {    Login: AuthNavigator,    App: AppNavigator  },  {    initialRouteName: 'Login'  });
const App = () => (  <SwitchNavigator />);
export default App;

What do we see here?

  1. We import and invoke the createSwitchNavigator module

2. On invocation we provide 2 configuration objects: the former contains the flows’ mapping, while the latter indicates the starting flow of the total app’s navigation flow.

How to actually navigate through views

React Navigation passes a prop called navigation in every view. This prop is an object that carries the available navigation methods with it. The most common methods we need to use are the following:

  • push: used with Stack Navigator only and pushes the new route object into the stack. It can be attached to a button click and navigates to a new view from which we can go back. I.e:
this.props.navigation.push('Profile');
  • pop: used with Stack Navigator only and and pops the last route object from the stack. It is automatically attached to the default header that React Navigation adds but if we remove it, like we did before, we need to attach it to a custom back button of our own. We also need to attach it to Android Back Button functionality. I. e.
this.props.navigation.pop();
  • replace: used with Stack Navigator only and replaces the whole stack with the new object. It is attached to a button click, exactly as the push method but there is no going back here. I.e.
this.props.navigation.replace('Home');
  • openDrawer: used with Drawer Navigator only and opens the menu screen that is configured for this purpose. It is attached to the button that opens the menu screen. I.e.
this.props.navigation.openDrawer();
  • navigate: used with all navigator types and navigates to the screen instructed. For the stack navigator it works similarly as the push method, but as pointed out by Luís Mestre in the comment section, it’s not exactly the same. In example, if you navigate to a screen that is already present in the stack, the navigate method will not add it again in the stack, but instead it will pop all the screens saved in the stack on top of it, until it reaches the one to navigate. For the drawer/tab navigators, it simply takes the user to the next view and stack object is not relevant.
this.props.navigation.navigate('Profile')
  • goBack: used with Stack Navigator only and has exactly the same functionality as pop method. I.e.
this.props.navigation.goBack();

In case you want to see the complete list of methods and other possible capabilities over the navigation prop have a look at the respective documentation link.

What do you think?

What do you think about this article? What is your library of choice when it comes to React Native? Offer your perspective and ideas in the comments section below.

If you enjoyed this article, feel free to hit that clap button ? to help others find it.