How to do it...

In the React part of this book, we built a complete routing solution, including public and protected routes, using a login view to enter the user's name and password. In a mobile application, since the user is more restricted, we can just make do by enabling a login at the beginning, and enabling the normal navigation afterward. All the work with usernames, passwords, and tokens is basically the same as before, so for now, let's only worry about navigation, which is different in RN, and forget the common details.

For starters, let's have some views—a empty screen with some centered text will do:

// Source file: src/routingApp/screens.js

/* @flow */

import React, { Component } from "react";
import {
Button,
Image,
StyleSheet,
Text,
TouchableOpacity,
View
} from "react-native";

const myStyles = StyleSheet.create({
fullSize: {
flex: 1
},
fullCenteredView: {
flex: 1,
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
bigText: {
fontSize: 24,
fontWeight: "bold"
},
hamburger: {
width: 22,
height: 22,
alignSelf: "flex-end"
}
});

// continues...

Then, to simplify creating all the needed views, let's have a makeSimpleView() function that will produce a component. We'll include a hamburger icon at the top right, which will open and close the navigation drawer; we'll see more on this later. We'll use this function to create most of our views, and we'll add a SomeJumps extra view, with three buttons that allow you to navigate directly to another view:

// ...continued

const makeSimpleView = text =>
class extends Component<{ navigation: object }> {
displayName = `View:${text}`;

render() {
return (
<View style={myStyles.fullSize}>
<TouchableOpacity
onPress={this.props.navigation.toggleDrawer}
>
<Image
source={require("./hamburger.png")}
style={myStyles.hamburger}
/>
</TouchableOpacity>
<View style={myStyles.fullCenteredView}>
<Text style={myStyles.bigText}>{text}</Text>
</View>
</View>
);
}
};

export const Home = makeSimpleView("Home");
export const Alpha = makeSimpleView("Alpha");
export const Bravo = makeSimpleView("Bravo");
export const Charlie = makeSimpleView("Charlie");
export const Zulu = makeSimpleView("Zulu");
export const Help = makeSimpleView("Help!");

export const SomeJumps = (props: object) => (
<View style={myStyles.fullSize}>
<Button
onPress={() => props.navigation.navigate("Alpha")}
title="Go to Alpha"
/>
<Button
onPress={() => props.navigation.navigate("Bravo")}
title="Leap to Bravo"
/>
<Button
onPress={() => props.navigation.navigate("Charlie")}
title="Jump to Charlie"
/>
</View>
);
Here, for simplicity, and given that we weren't using props or state, and that the view was simple enough, I used a functional definition for the SomeJumps component, instead of using a class, as in most other examples. If you want to revisit the concept, have a look at https://reactjs.org/docs/components-and-props.html.

Where does the navigation prop come from? We'll see more in the next section, but some explanation can be given here. Whenever you create a navigator, you provide it with a set of views to handle. All those views will get an extra prop, navigation, which has a set of methods you can use, such as toggling the visibility of the drawer, navigating to a given screen, and more. Read about this object at https://reactnavigation.org/docs/en/navigation-prop.html.

Now, let's create the drawer itself. This will handle the sidebar menu and show whatever view is needed. The createDrawerNavigator() function gets an object with the screens that will be handled, and a set of options; here, we just specified the color of the drawer itself and its width (there are plenty more possibilities, which are detailed at https://reactnavigation.org/docs/en/drawer-navigator.html):

// Source file: src/routingApp/drawer.js

/* @flow */

import { createDrawerNavigator } from "react-navigation";

import {
Home,
Alpha,
Bravo,
Charlie,
Zulu,
Help,
SomeJumps
} from "./screens";

export const MyDrawer = createDrawerNavigator(
{
Home: { screen: Home },
Alpha: { screen: Alpha },
Bravo: { screen: Bravo },
Charlie: { screen: Charlie },
Zulu: { screen: Zulu },
["Get Help"]: { screen: Help },
["Some jumps"]: { screen: SomeJumps }
},
{
drawerBackgroundColor: "lightcyan",
drawerWidth: 140
}
);

The result of createDrawerNavigation() is itself a component that will take care of showing whatever view is selected, showing and hiding the drawer menu, and so on. We only need to create the main application itself.

Next, let's creating our navigable application, since we now have a set of views and a drawer navigator to handle them. The main view for our application is then quite simple—check out its .render() method, and you'll have to agree:

// Source file: App.routing.js

/* @flow */

import React from "react";
import { StatusBar } from "react-native";

import { MyDrawer } from "./src/routingApp/drawer";

class App extends React.Component {
render() {
return (
<React.Fragment>
<StatusBar hidden />
<MyDrawer />
</React.Fragment>
);
}
}

export default App;

An interesting point: since navigators are components. If you so wish, you can have a navigator within another navigator! For example, you could create a TabNavigator, and include it in a drawer navigator: when the corresponding option is selected, you'll get a tabbed view onscreen, now governed by the tab navigator. You can compose navigators in any way you wish, allowing for very complex navigation structures, if you want.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset