Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Using Navigator Routes In Your React Native Application

TwitterFacebookRedditLinkedInHacker News

When creating a mobile application, chances are at some point in time you’re going to want to have more than one application view or screen. In many programming languages this is referred to as application routes.

With React Native, the navigator is used to switch between screens.

Previously I wrote about how to change between views in Ionic Framework using the AngularJS UI-Router. This time we’ll be using the React Native NavigatorIOS component, but both will have similar goals.

Before going any further it is important to note that as of now React Native only works for iOS. This means you must be using a Mac computer to develop with.

With React Native already installed, execute the following from your Terminal:

react-native init ReactProject

No additional plugins or libraries are required at this point.

The application we are building will have two different screens. We’ll have a login screen that allows the user to enter a username and password and we’ll have a secure screen that just presents what the user has entered. We’re not actually doing any authentication because for this tutorial we’re only interested in navigation.

Open the project’s index.ios.js file and add the following code:

"use strict";

var React = require("react-native");

var {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    NavigatorIOS,
} = React;

var LoginView = require("./LoginView");

var ReactProject = React.createClass({
    render: function() {
        return (
            <NavigatorIOS
                style={styles.navigationContainer}
                initialRoute={{
                title: "Navigator Example",
                component: LoginView,
            }} />
        );
    }
});

var styles = StyleSheet.create({
    navigationContainer: {
        flex: 1
    }
});

AppRegistry.registerComponent("ReactProject", () => ReactProject);

A few things to note about the root JavaScript file:

  1. We are including the NavigatorIOS tag
  2. We are requiring the LoginView class which we’ll create later. This is the first screen the user will see
  3. We’re rendering the NavigatorIOS, giving the first screen a title, and setting the first screen as the LoginView class
  4. We are creating a style for the navigation

With that out of the way, let’s move on to the code for the LoginView class. Create a file called LoginView.js at the root of your project and add the following code:

"use strict";

var React = require("react-native");

var {
    Component,
    StyleSheet,
    Text,
    TextInput,
    TouchableHighlight,
    View,
} = React;

var SecureView = require("./SecureView");

class LoginView extends Component {

    constructor(props) {
        super(props);
        this.state = {
            username: "",
            password: ""
        };
    }

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.title}>
                    Sign In
                </Text>
                <View>
                    <TextInput
                        placeholder="Username"
                        onChange={(event) => this.setState({username: event.nativeEvent.text})}
                        style={styles.formInput}
                        value={this.state.username} />
                    <TextInput
                        placeholder="Password"
                        secureTextEntry={true}
                        onChange={(event) => this.setState({password: event.nativeEvent.text})}
                        style={styles.formInput}
                        value={this.state.password} />
                    <TouchableHighlight onPress={(this.onSubmitPressed.bind(this))} style={styles.button}>
                        <Text style={styles.buttonText}>Submit</Text>
                    </TouchableHighlight>
                </View>
            </View>
        );
    }

    onSubmitPressed() {
        this.props.navigator.push({
            title: "Secure Page",
            component: SecureView,
            passProps: {username: this.state.username, password: this.state.password},
        });
    }

};

var styles = StyleSheet.create({
    container: {
        padding: 30,
        marginTop: 65,
        alignItems: "stretch"
    },
    title: {
        fontSize: 18,
        marginBottom: 10
    },
    formInput: {
        height: 36,
        padding: 10,
        marginRight: 5,
        marginBottom: 5,
        marginTop: 5,
        flex: 1,
        fontSize: 18,
        borderWidth: 1,
        borderColor: "#555555",
        borderRadius: 8,
        color: "#555555"
    },
    button: {
        height: 36,
        flex: 1,
        backgroundColor: "#555555",
        borderColor: "#555555",
        borderWidth: 1,
        borderRadius: 8,
        marginTop: 10,
        justifyContent: "center"
    },
    buttonText: {
        fontSize: 18,
        color: "#ffffff",
        alignSelf: "center"
    },
});

module.exports = LoginView;

There is a lot going on here so lets break it down into smaller chunks.

var SecureView = require("./SecureView");

The above line includes the SecureView class that we’re going to create soon. We are including it so that we can navigate to it.

Next we’re using a constructor to initialize some things:

constructor(props) {
    super(props);
    this.state = {
        username: "",
        password: ""
    };
}

The props variable we are passing is for any passed variables. We’re not passing any to the LoginView, but we will be for the SecureView in a moment. The username and password variables are being initialized as blank.

This brings us to the render function. Instead of explaining everything, I’m just going to brush over the important part of this function:

<TextInput
    placeholder="Username"
    onChange={(event) => this.setState({username: event.nativeEvent.text})}
    style={styles.formInput}
    value={this.state.username} />
<TextInput
    placeholder="Password"
    secureTextEntry={true}
    onChange={(event) => this.setState({password: event.nativeEvent.text})}
    style={styles.formInput}
    value={this.state.password} />
<TouchableHighlight onPress={(this.onSubmitPressed.bind(this))} style={styles.button}>
    <Text style={styles.buttonText}>Submit</Text>
</TouchableHighlight>

The <TextInput> tags have an onChange method. Every time text is changed, we use a lambda function to set the state variable. This is important because the state variable is what will be passed to the next view.

The <TouchableHighlight> tag calls the onSubmitPressed function when clicked. This function is what navigates to a different route.

this.props.navigator.push({
    title: "Secure Page",
    component: SecureView,
    passProps: {username: this.state.username, password: this.state.password},
});

We’re pushing a view into the history stack. The username and password states are passed as properties to the next route. The last part of this file is the styles, but we’re not going to worry too much about that as it isn’t an important part of this article.

Finally let’s take a look at our SecureView class. Create a file called SecureView.js at the root of your project and add the following code:

"use strict";

var React = require("react-native");

var {
    Component,
    StyleSheet,
    Text,
    View,
} = React;

class SecureView extends Component {

    constructor(props) {
        super(props);
        this.state = {
            username: this.props.username,
            password: this.props.password
        };
    }

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.heading}>
                    Welcome {this.props.username}!
                </Text>
                <Text style={styles.subheading}>
                    Your password is {this.props.password}
                </Text>
            </View>
        );
    }

};

var styles = StyleSheet.create({
    container: {
        padding: 30,
        marginTop: 65,
        alignItems: "center"
    },
    heading: {
        marginBottom: 20,
        fontSize: 18,
        textAlign: "center",
        color: "#656565"
    },
    subheading: {
        color: "#cccccc"
    }
});

module.exports = SecureView;

Like the LoginView class, the SecureView class is pretty large as well. To make it easier we’re going to look at it in parts.

This class isn’t structured too differently than the LoginView class. The most important part of this is the constructor:

constructor(props) {
    super(props);
    this.state = {
        username: this.props.username,
        password: this.props.password
    };
}

Notice that we’re setting the username and password state variables as whatever was passed in as properties. With the state variables set, we can show them on the screen in the render function.

We’ll skip over the rest because we’ve seen it all before.

React Native Navigator

Above is what the application should look like.

Conclusion

At some point in time you’re going to want more than one screen in your React Native application. This can be accomplished with the navigator component and a selection of route files. Variables can easily be passed to different routes with the React Native navigator as well.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.