Log In

React Native Common Components


by Yariv Katz

In this article we will cover the common components we can use in React Native and how to use them.

bootstrap React Native

We will start with bootstraping a new react native project.

> npx react-native-cli init RnComponents
> npm start
> react-native run-ios

Although we are using Javascript for programming in react native, we are bound to the environment react native has created for us. This means that we can't use all the globals we used when programminng for the web. Same goes for using HTML in our components, we can't use div and h tags we now have to use react native components to create our view. The most basic component we will use is the View.

View

The View component is similar to a div when programming for the web. The View represents a block on our screen. a View can take the entire screen or part of it, we usually place it on the screen using flex styling. Let's create a View that will fill the entire screen with a background color of red, and a vertical center View taking 50% of the screen with a blue background. Modify the root component App.js

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

type Props = {};
export default class App extends Component<Props> {
    render() {
        return (
        <View style={styles.fullHeight}>
            <View style={styles.halfHeight} />
        </View>
        );
    }
}

const styles = StyleSheet.create({
    fullHeight: {
        backgroundColor: 'red',
        flex: 1,
        justifyContent: 'center'
    },
    halfHeight: {
        backgroundColor: 'blue',
        height: '50%'
    }
});

We style and position our views with StyleSheet.create ans we position the views with flex. The components we will create will usually be wrapped in a div.

Text

Text component will be used to display various text in various fonts. It's the equivelant of Header (h1, h2, ...) tags or paragraph tag (p) in web. Let's display some text in the blue view. Modify the file App.js.

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

type Props = {};
export default class App extends Component<Props> {
    render() {
        return (
        <View style={styles.fullHeight}>
            <View style={styles.halfHeight}>
            <Text style={ {fontFamily: 'Cochin', textAlign: 'center'} }>
                <Text style={ {fontWeight: 'bold', fontSize: 25} }>
                Header
                </Text>
                {'\n'}
                <Text style={ {fontSize: 18} }>
                Body
                </Text>
            </Text>
            </View>
        </View>
        );
    }
}

const styles = StyleSheet.create({
    fullHeight: {
        backgroundColor: 'red',
        flex: 1,
        justifyContent: 'center'
    },
    halfHeight: {
        backgroundColor: 'blue',
        height: '50%'
    }
});

The Text components can be nested to make common styles in parent that children will inherit.

Button

Let's go over some of the form controls we have to interact with user actions. The most popular form control we will use is a button. Let's create a button that will generate a random number on the screen when pressed. We will use react native built in Button and also install a popular button built by the community called react-native-button First we will install the community package button:

> npm install react-native-button --save

Now modify the file App.js

import React, {Component} from 'react';
import {StyleSheet, View, Text, Button} from 'react-native';
import RNButton from 'react-native-button';

type Props = {};
export default class App extends Component<Props> {
    state = {
        num: Math.random()
    }

    generateNumber = () => {
        this.setState({
        num: Math.random()
        })
    }

    render() {
        return (
        <View style={styles.fullHeight}>
            <View style={styles.halfHeight}>
            <Text style={ {fontFamily: 'Cochin', textAlign: 'center'} }>
                <Text style={ {fontWeight: 'bold', fontSize: 25} }>
                Header
                </Text>
                {'\n'}
                <Text style={ {fontSize: 18} }>
                Random number {this.state.num}
                </Text>
            </Text>
            <Button 
                title="Generate number"
                onPress={this.generateNumber}
            />
            <RNButton
                onPress={this.generateNumber}
                style={ {
                justifyContent: 'center',
                fontSize: 20, 
                backgroundColor: 'green', 
                borderStyle: 'solid',
                borderColor: 'black',
                width: 200, 
                paddingTop:20,
                paddingBottom:20,
                overflow: 'hidden',
                color: 'black',
                borderRadius: 10} }
            >
                Generate number2
            </RNButton>
            </View>
        </View>
        );
    }
}

const styles = StyleSheet.create({
    fullHeight: {
        backgroundColor: 'red',
        flex: 1,
        justifyContent: 'center'
    },
    halfHeight: {
        backgroundColor: 'blue',
        height: '50%'
    }
});

I didn't find a way to style the react native built in Button, but the button from the library we installed can accept a style property where you can style the button. Another recommended and popular library you can use that contains Button as well is React Native Elements Our buttons will create a new number in the state and we are displaying that number in the render method.

TextInput

The next popular form element we use in our app is a TextInput where a user can type text. Let's create a component that takes the user name and print an hello message. Create a folder in your app called: components and in it create a file called Name.js with the following code:

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

export default class Name extends Component {
    state = {
        text: null
    }

    setName = () => {
        this.setState((prevState) => {
            return {
                name: prevState.text
            }
        })
    }

    render() {
        return (
            <View>
                <TextInput
                    autoFocus
                    maxLength={100}
                    value={this.state.text}
                    onChangeText={(text) => this.setState({text})}
                    placeholder="Type your name"
                />
                <Button
                    title="Submit"
                    onPress={this.setName}
                />
                { this.state.name ? <Text>Hello {this.state.name}</Text> : null}
            </View>
        )
    }
}

The text input is a controled form component since the value is from the state and the value in from the OnChangeText is populating the state. When the button is pressed we are modifying the name in the state and displaying the name the user typed.

Image

Let's say we want to display an image in our app. To do this we will use the Image component. Let's create a component that displays a logo image. In the components folder, create a folder called logo Copy to that folder an image named logo.png, in the logo folder add another file Logo.js With the following code:

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

export default class Logo extends Component {
    render() {
        return (
            <Image
                source={require('./logo.png')}
                style={ {width: 50, resizeMode: 'contain'} }
            />
        )
    }
}

The source of the image can be a local file it can also be a remote uri or a data uri. We can add styles to the image as well.

FlatList

The FlatList is a high performant list that renders on the screen only the items that are currently displayed. Let's first start with a simple example of a flat list. We will have an hardcoded list of users where each object contains user first name and last name. We will create a component to display those users. In the components folder, create a file called Users.js with the following code:

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

export default class Users extends Component {
    state = {
        users: [
            {firstName: 'Yariv', lastName: 'Katz'},
            {firstName: 'Hello', lastName: 'World'},
            {firstName: 'Foo', lastName: 'Bar'},
        ]
    }

    changeData = () => {
        this.setState((prevState) => {
            const newState = {...prevState};
            newState.users[0].firstName = 'Bugeez.io';
            return newState;
        })
    }

    changeDataReference = () => {
        this.setState((prevState) => {
            const newState = {...prevState}
            newState.users = [...newState.users] 
            newState.users[0] = {...newState.users[0], firstName: 'Bugeez.io'};
            return newState;
        })
    }

    render() {
        return (
            <View>
                <FlatList 
                    data={this.state.users}
                    renderItem={({item}) => <Text style={{ color: 'black'}}>{item.firstName} {item.lastName}</Text>}
                    keyExtractor={(item) => item.firstName}
                />
                <Button
                    title="same reference change"
                    onPress={this.changeData}
                />
                <Button
                    title="change reference"
                    onPress={this.changeDataReference}
                />
            </View>
            
        );
    }
}

The FlatList is really easy to use. We are passing the data property with the data in the list, we are also passing a renderItem property that will be called with the data items and will determine how each element will look like. Each element in our list is a Text component displaying the name of the user. We placed two button to change the data, one will keep the same users array reference and change an item in the data, and the other will clone the array to a new reference and then change the data. Notice that the list is a PureComponent so it won't render if the data is the same reference. Let's do a more complex component that envolves fetching todo tasks from our todo server. In our components folder, create a file called Todo.js with the following:

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

export default class Todo extends Component {
    state = {
        tasks: []
    }

    async componentDidMount() {
        const res = await fetch('https://nztodo.herokuapp.com/api/task/?format=json');
        const json = await res.json();
        this.setState({
            tasks: json
        })
    }

    render() {
        return (
            <FlatList 
                data={this.state.tasks}
                renderItem={({item}) => (
                    <View>
                        <Text>{item.title}</Text>
                        <Text>{item.description}</Text>
                    </View>
                    )}
                keyExtractor={(item) => item.id.toString()}
            />
        )
    }
}

in the componentDidMount we are fetching the items from the server and setting the state with the new todo tasks. This will cause a re render and will show the list in the FlatList.

Summary

In this article we covered the main components used to build a react application. Of course this is just the tip of the iceberg, there are many other components and we recommend to just experiment with the other component braught to us by react native. In the future we will do a follow up article on more advanced components that we didn't cover in this article. Other then the built in components the community of react native is massive and creating amazing components that looks great and are extremly easy to use. The community of react native is what makes this technology the best choice for cross platform mobile solution.