React Native and How to Start Your First Application

Introduction

If you are a front-end or mobile developer, chances are that you have already heard of react native. React Native lets you build mobile applications for both Android and iOS platforms using the same code. It’s worth it to mention that those are real applications; the same kinds as you would make in Java, Kotlin, or Objective-C. React Native is almost identical to React. You will see it yourself after we finish building our first simple application.

Initializing the Project with Create React Native App

Install “create-react-native-app” globally using npm or yarn, although, as of now, it is not recommended that you use npm version 5. You should rather downgrade it to 4 or use yarn instead. I will be using npm, since that is what most people use.

npm i -g create-react-native-app

Create a Basic Project Using “create-react-native-app.” I will name mine “TestApp.”

create-react-native-app TestApp

Go to the created directory.

cd TestApp

You could just start working on this project. However, the “create-react-native-app” creates only the basic project structure, which limits your ability to scale it up. If you want to have a standard react native structure, you can do so by ejecting the “create-react-native-app.” To find out more about ejecting from CRNA, visit this link: https://github.com/react-community/create-react-native-app/blob/master/ EJECTING.md

During the ejection process, you will be asked 3 questions, in the first one, just accept “React Native: I’d like a regular React Native project.” In the second, type the name for your app, and in the last one, the name of your project. If you want, you can later change these names in “app.json.”

npm run eject

Make sure you have Xcode/Android Studio installed and a connected device or emulator, then you can run your app.

npm run android

If you encounter the following error: “SDK location not found,” you will have to create a file in the main android directory “./android/” named “local.properties” and specify the absolute path to your SDK, e.g. “sdk.dir = /Users/username/Library/Android/sdk.” Once you successfully run your application, you can debug it using Chrome Developer Tools here at http://localhost:8081/debugger-ui/

Creating Your First Component

“App.js” is the starting point of your Application that you are bootstrapping in “index.js.” As you can see, it is just a regular React component. The only difference is that you are using predefined components from “react-native.”

We will start by creating a folder to hold our components. Please note that this will be a very simple app. In a real-world scenario, you would divide the folder structure differently.

mkdir components
cd components

Inside, we will create a new file “HomeView.js” and create a basic React component with the same name, nothing fancy for now.

import React, { Component } from 'react';

class HomeView extends Component {
    render() {
        return ();
    }
}

export default HomeView

Now, we have to display something here. Import the “Text” component from the “react-native” and use it to display the text in the return statement.

import React, { Component } from 'react';
import { Text } from 'react-native';

class HomeView extends Component {
    render() {
        return (
            <Text>
                Sample Text
            </Text>
        );
    }
}

export default HomeView

After this, go back to “App.js” and import your component and display it inside the “View” component. Our component will take up the whole screen, so we can remove the last few styles. You can now rerun your app and you should see specified text displayed on your device/emulator.

import React from 'react';
import { StyleSheet, View } from 'react-native';
import HomeView from './components/HomeView';

export default class App extends React.Component {
    render() {
        return (
            <View style={styles.container}>
                <HomeView />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
});

Styling

The component is working. However, we would probably like to style it. First of all, import “View” from “react-native” and wrap it around your “Text” component. You probably know what “Text” is for, but you may be confused about the “View” component, which, basically speaking it’s just a container. It doesn’t have one specific purpose, so you can use it the same as you would use a “div” tag in HTML.

To style individual components, we will import “StyleSheet” from “react-native” and use its function “create” to create an object holding our styles. Attributes and their values are usually the same, as they would be in CSS, but written in Camel Case.

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#06f'
    },
    text: {
        paddingBottom: 14,
        color: '#fff',
        fontSize: 24,
    }
});

After we specify our styles, we can assign them to components by using “style” prop.

return (
    <View style={styles.container} >
        <Text style={styles.text}>
            Sample Text
        </Text>
    </View>
);

The app looks better, but it is still far from perfect. It could use some fancy background gradient. Unfortunately, we cannot create gradients like we would do in CSS. We have to use a specific component like “react-native-linear-gradient.” After you have installed the package, you will have to link the project using “react-native link,” otherwise react-native will not detect any changes.

npm install –save react-native-linear-gradient
react-native link

We will have to import it and use as a wrapper for our code. In this example we can just substitute “View” for it. To specify colours for the gradient, you can pass an array with them to the “colours” prop. You can remove “backgroundColor” from styles as well, as we won’t need it any longer.

import React, { Component } from 'react';
import { Text, StyleSheet } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';

class HomeView extends Component {
    render() {
        return (
            <LinearGradient colors={['#650aff', '#f4a']} style={styles.container} >
                <Text style={styles.text}>
                    Sample Text
                </Text>
            </LinearGradient>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    text: {
        paddingBottom: 14,
        color: '#fff',
        fontSize: 24,
    }
});

export default HomeView

Navigation

To create navigation, we will use “StackNavigator” from “react-navigation” (Remember to install it beforehand.). It’s a function that returns component with implemented navigation. As the first argument, we have to pass an object with our routes, and the second is for options, where we can specify our initial route. We can implement it in a separate file and use it as a regular component in our “App.js.”

import React from 'react';
import { StackNavigator } from 'react-navigation';
import HomeView from './HomeView';

const Routing = StackNavigator({
    HOME: { screen: HomeView },
},
{
    initialRouteName: 'HOME',
});

export default Routing
import React from 'react';
import { StyleSheet, View } from 'react-native';
import Routing from './components/Routing';

export default class App extends React.Component {
    render() {
        return (
            <View style={styles.container}>
                <Routing />
            </View>
        );
    }
}

You can now see the navigation bar on your application. It is no use now, so we will create the second component and add it as a second route.

import React, { Component } from 'react';
import { Text, StyleSheet } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';

class SecondView extends Component {
    render() {
        return (
            <LinearGradient colors={['#4ff', '#f4a']} style={styles.container} >
                <Text style={styles.text}>
                    Second view
                </Text>
            </LinearGradient>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    text: {
        paddingBottom: 14,
        color: '#fff',
        fontSize: 24,
    }
});

export default SecondView
const Routing = StackNavigator({
        HOME: { screen: HomeView },
        SECOND: { screen: SecondView }
    },
    {
        initialRouteName: 'HOME',
    });

Now, when we have routing, we have to move between our screens somehow. Each of our components added to navigation has function “navigate” under “props.navigation.navigate,” which we can use to switch between our two views. We will create a button in both components that will call the mentioned function in an onPress callback, and navigate us to another route.

import React, { Component } from 'react';
import { Text, StyleSheet, Button } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';

class HomeView extends Component {
    switchPage = () => this.props.navigation.navigate('SECOND');

    render() {
        return (
            <LinearGradient colors={['#650aff', '#f4a']} style={styles.container} >
                <Text style={styles.text}>
                    Sample Text
                </Text>
                <Button onPress={this.switchPage} title={'Next screen'} />
            </LinearGradient>
        );
    }
}

As you can see we, cannot only move between views with our button, but we can also go back with an arrow in the navigation bar or by using your phone’s back button. Each route change that we call with the “navigate” function will add a new view to the “stack” of all visited routes. That’s why it is called a “StackNavigator.” If you want to, you can remove the navigation bar by setting the “HeaderMode” setting to “none.”

const Routing = StackNavigator({
        HOME: { screen: HomeView },
        SECOND: { screen: SecondView }
    },
    {
        initialRouteName: 'HOME',
        headerMode: 'none'
    });

There are more types of navigators, for example “NavigatorIOS.” You have to see for yourself and choose the one that best suits your application. If you want to learn more about “react-navigation,” visit https://reactnavigation.org/docs/getting-started.html

Data Binding

We can switch between routes, but usually, you would want to exchange some information between them as well. Fortunately, “navigate” provides us the ability to specify an object with props to be passed into our route, but first we have to define that information. We will ask the user to type his name into the input in “SecondView” and save it in our state, and then we can pass that name to the initial component and display it to the user.

Let’s start by defining our state with a name variable and function to update it.

class SecondView extends Component {
    constructor(props) {
        super(props);

        this.state = {
            name: '',
        }
    }

    switchPage = () => this.props.navigation.navigate('HOME');

    onChangeTextHandler = val => this.setState({name: val});

    render() {
        ...

Then substitute the Text component with “TextInput” and add our handler to “onChangeText” callback. We can also specify a minimum width for the input.

class SecondView extends Component {
    constructor(props) {
        super(props);

        this.state = {
            name: '',
        }
    }

    switchPage = () => this.props.navigation.navigate('HOME', { name: this.state.name });

    onChangeTextHandler = val => this.setState({name: val});

    render() {
        const { name } = this.state;

        return (
            <LinearGradient colors={['#4ff', '#f4a']} style={styles.container} >
                <TextInput
                    style={styles.input}
                    value={name}
                    placeholder={'Type your name'}
                    onChangeText={this.onChangeTextHandler}
                />
                <Button onPress={this.switchPage} title={'Next screen'} />
            </LinearGradient>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    input: {
        minWidth: 200,
        paddingBottom: 14,
        color: '#fff',
        fontSize: 24,
    }
});

This is a good time to check to see if the Input displays and works as expected. If yes, we can pass an object with our name as the second argument of the “navigate” function.

render() {
    const { name } = this.state;

    return (
        <LinearGradient colors={['#4ff', '#f4a']} style={styles.container} >
            <TextInput
                style={styles.input}
                value={name}
                placeholder={'Type your name'}
                onChangeText={this.onChangeTextHandler}
            />
            <Button onPress={this.switchPage} title={'Next screen'} />
        </LinearGradient>
    );
}

Now we have to display a name in the “HomeView.” If no value is specified or its length is 0, we will provide a default value.

render() {
    const { state } = this.props.navigation;
    const { params } = state;
    const name = (params && params.name.length > 0) ? params.name : 'Stranger';
    const message = `Hello ${name}!`;

    return (
        <LinearGradient colors={['#650aff', '#f4a']} style={styles.container} >
            <Text style={styles.text}>
                { message }
            </Text>
            <Button onPress={this.switchPage} title={'Next screen'} />
        </LinearGradient>
    );
}

Summary

Those were the very basics of what is needed to begin building your own React Native application. Here are some links that will help you learn about the new features and will show you some good practices as well.