React Native + Expo Documentation

React Native Documentation

React Native lets you build native mobile apps using JavaScript and React.

Expo Documentation

Expo is a set of tools, libraries and services which let you build native iOS and Android apps by writing JavaScript. On CodeHS, you can use Expo in your React Native programs.

React Native File Skeleton

This is a simple React Native file skeleton that you can use to get started on a project. To get info on specific parts, see below.

import React, { Component } from 'react';
import { AppRegistry, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';

export default class App extends Component {
    render() {
        return (
            <View>
                <Text>
                    Hello, world!
                </Text>
            </View>
        );
    }
}

The import statements that appear at the top of the file are needed to import items from outside our app and inform the computer that we are calling on the React Native library and unique syntax. Here, the second import statement is importing three components- AppRegistry, View, and StyleSheet. AppRegistry and View must always be imported and as programs become more complex, even more components will need to be imported in this statement.

The export statement is needed to export the information to be rendered correctly. The syntax of this statement will stay the same for the purposes of this course.

The render function below tells our app what to render. All of the components used to create our app are written inside this function.

Components

Many components can be used to build your app. This React Native Documentation can be used to get more information on those discussed below as well as others.

View

The view component is the most fundamental component for building a user interface. A parent view component is needed to hold all components of your app. Additional view components can be nested inside the parent as well. Each view component must have an opening and closing tag. View must be imported at the top of the program.The example below shows a text and view component nested inside the parent view component. The second view component could be used as a button, for example.

export default class App extends Component {
    render() {
        return (
            <View>
                <Text>
                    Hello
                </Text>
                <View>
                </View>
            </View>
        );
    }
}

Text

A text component can be used to print text to the screen. Each text component must have an opening and closing tag. Text must be imported at the top of the program. The example below shows two text components nested inside a parent view component.

export default class App extends Component {
    render() {
        return (
            <View>
                <Text>
                    Hello
                </Text>
                <Text>
                    World!
                </Text>
            </View>
        );
    }
}

Image

An image component can be used to display images on the screen. An image component only has an opening tag, which contains the image uri, height, and width. Image must be imported at the top of the program. The example below shows a text component below an image component. All components are nested inside a parent view component.

export default class App extends Component {
    render() {
        return (
            <View>
                <Image
                    source={{ uri: 'http://d23dyxeqlo5psv.cloudfront.net/cat.gif' }}
                    style={{ height: 140, width: 200 }}
                />
                <Text>
                    Bad Kitty
                </Text>
            </View>
        );
    }
}

ScrollView

A ScrollView component can be used to wrap certain components on the screen and allow the user to scroll through items. A ScrollView component must have an opening and closing tag. ScrollView must be imported at the top of the program. The example below shows 3 sets of text components nested inside view components. All components are nested inside a ScrollView component which is inside a parent view component.

export default class App extends Component {

    render() {
        return (
            <View>
                <ScrollView>
                    <View>
                        <Text>
                            Period: 1
                        </Text>
                        <Text>
                            Introduction to Computer Science
                        </Text>
                    </View>
                    <View>
                        <Text>
                            Period: 2
                        </Text>
                        <Text>
                            AP Computer Science Principles
                        </Text>
                    </View>
                    <View>
                        <Text>
                            Period: 3
                        </Text>
                        <Text>
                            Introduction to Python
                        </Text>
                    </View>
                </ScrollView>
            </View>
      )
   }
}

Look at the React Native ScrollView Docs for more information on ScrollView components.

Stylesheet API

The Stylesheet API can be used to style our app. We need to import StyleSheet at the beginning of our program to inform our app that we are using the Stylesheet attributes and values. The example below shows two view components and a text component being styled using the Stylesheet.

import React, { Component } from 'react';
import { AppRegistry, View, Text, StyleSheet } from 'react-native';
import Constants from 'expo-constants';

export default class App extends Component {
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.titleBox}>
                    <Text style={styles.titleText}>
                        Welcome to my app!
                    </Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    },
    titleBox: {
        height: 100,
        width: 200,
        backgroundColor: 'red',
        borderColor: 'yellow',
        borderWidth: 10,
        justifyContent: 'center'
    },
    titleText: {
        color: 'white',
        fontFamily: 'Roboto',
        fontWeight: 'bold',
        fontSize: 32,
        textAlign: 'center',
    },
});

For a full list of properties and values that can be used to style:

Stylesheet Properties

This section covers some of the most commonly used Stylesheet properties and values. For a full list of possible Stylesheet properties and values, visit the React Native Stylesheet Docs.

Component Layout Properties

There are multiple attributes that can be used to style the layout of your app. A few common properties are shown below.

The justifyContent attribute sets the way components are laid out vertically (along the y-axis). This property can be set to: 'flex-start', 'flex-end', 'center', 'stretch', 'baseline'

The alignItems attribute sets the way components are laid out horizontally (along the x-axis). This property can be set to: 'flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'space-evenly'

The following example centers three view components in the center of the screen, stacked on top of one another.

import React, { Component } from 'react';
import { AppRegistry, View, Text, StyleSheet } from 'react-native';
import Constants from 'expo-constants';

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


const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    },
    topBox: {
        width: 100,
        height: 100,
        backgroundColor: 'lightBlue',
    },
    middleBox: {
        width: 100,
        height: 100,
        backgroundColor: 'mediumBlue',
    },
    bottomBox: {
        width: 100,
        height: 100,
        backgroundColor: 'darkBlue',
    },
});

To arrange items to be placed next to one another rather than stacked vertically, the flexDirection attribute can be set to 'row'.

Note: If the flexDirection is set to 'row', the alignItems and justifyContent attributes are switched (alignItems works along the y-axis, and justifyContent works along the x-axis).

Color

All information about colors in the Stylesheet can be found in the Colors docs.

Stylesheet Colors can either be:

Color Names

Common Color Names:

Names are not case-sensitive. "RED" is the same as "red" is the same as “Red”.

There are many valid color names. See a full list of all names here.

Example:

titleText: {
    color: 'Blue',
}

Result:

Hello

RGB Colors

Colors can also be represented by the RGB (Red Green Blue) color encoding system. Every color can be made just by mixing different amounts of red, green, and blue.

RGB color values can be specified in the Stylesheet using ‘rgb(red, green, blue)’.

Example:

titleText: {
    color: 'rgb(255, 0, 0)',
}

Result:

Hello

Hex Color Values

We can also represent RGB colors using hexadecimal values. 6 hexadecimal digits make up a color:

Example:

titleText: {
    color: '#00ff00',
}

Result:

Hello

Text and Font

color: text color in the selected element (any valid color name or code)

fontSize: size of the font (any numerical value)

fontFamily: font family (ex. ‘Arial’ or ‘Times’)

fontStyle: font style (‘italic’ or ‘normal’)

fontWeight: how thick the font is (bold or bolder, or a value from 100 to 900)

textAlign: sets the horizontal alignment of text (‘center’, ‘left’, ‘right’)

const styles = StyleSheet.create({
    titleText: {
        color: '#ffff00',
        fontFamily: 'Futura',
        fontStyle: 'italic',
        fontSize: 28,
        textAlign: 'left',
    }
});

Background

backgroundColor: background color in the selected element (any valid color name or code)

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

Borders

The border properties allow us to create borders around any element.


const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'rgb(0, 0, 255)',
        borderWidth: 10,
        borderBottomStyle: 'dotted',
        borderTopColor: 'lightBlue',
    }
});

Margins

The margin is the amount of space between an element and the elements around it. The margin is set with a value of pixels.

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'lightBlue'
    },
    box: {
        height: 100,
        height: 50,
        backgroundColor: 'Red',
        margin: 30
    }
});

TouchableHighlight

We can allow users to interact with components of our app by using the TouchableHighlight component. This component wraps another component and allows us to program an event to occur when that component is tapped. Each TouchableHighlight component must have an opening and closing tag. TouchableHighlight must be imported at the top of the program. In this example, a text component is being wrapped inside a TouchableHighlight button component and an alert is being shown when the button is pressed.

import React, { Component } from 'react';
import { AppRegistry, View, Text, StyleSheet, TouchableHighlight, Alert } from 'react-native';
import Constants from 'expo-constants';

export default class App extends Component {
    render() {
        return (
            <View style={styles.container}>
                <TouchableHighlight
                    style={styles.touchableButton}
                    onPress={() => {
                        alert('Alert Message!');
                    }}
                >
                    <Text style={styles.buttonText}>
                        Press me!
                    </Text>
                </TouchableHighlight>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'white',
    },
    touchableButton: {
        backgroundColor: '#55acee',
        height: 100,
        width: 300,
        alignItems: 'center',
        justifyContent: 'center',
    },
    buttonText: {
        color: 'white',
        fontWeight: 'bold',
        fontSize: 24,
    }
});

Additional information about handling touches in your programs can be found in the React Native Documentation.

State

We can use state to alter aspects of our program based on interaction by the user. The initial state of variables are set before our render function. Any functions to be completed should also be defined here along with the changes to any variable values. To use the state variables in your program, we use {this.state.variable}. In the example below, a variable team is being created with the initial state set to “Red”. A second variable round is created and set to a value of 1. When the button is pressed, the newState function is called and the team variable is updated to “Blue” and the round variable is updated to 1 more than the previous value.

import React, { Component } from 'react';
import { AppRegistry, View, Text, StyleSheet, TouchableHighlight} from 'react-native';
import Constants from 'expo-constants';

export default class App extends Component {
   state = {
        team: "Red",
        round: 1
    }

    newState = () => {
        this.setState ({
            team: "Blue",
            round: this.state.round + 1
        })
    }

    render() {
        return (
            <View style={styles.container}>
                <TouchableHighlight style={styles.touchableButton}
                onPress = {this.newState}>
                    <Text style={styles.paragraph}>
                        {this.state.team}
                    </Text>
                </TouchableHighlight>
                <Text style={styles.paragraph}>
                    {this.state.round}
                </Text>
            </View>
      );
   }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'lightBlue',
    },
    touchableButton: {
        backgroundColor: '#55acee',
        height: 100,
        width: 300,
        alignItems: 'center',
        justifyContent: 'center',
        margin: 20
    },

    paragraph: {
        color: 'darkBlue',
        fontSize: 40,
        textAlign: 'center',
    },
});

Additional Interaction

There are many more features you can add to your React Native programs. Copy and paste the examples below into the editor to see what they do and how to use the features in your programs! Check out the React Native Documentation for more information.

Switch

import React, { Component } from 'react';
import { AppRegistry, View, StyleSheet, Switch} from 'react-native';
import Constants from 'expo-constants';

export default class App extends Component {
    state = {
        switchValue: true
    };

    _handleToggleSwitch = () => this.setState(state => ({
        switchValue: !state.switchValue
    }));

    render() {
        return (
            <View style={styles.container}>
                <Switch
                    onValueChange={this._handleToggleSwitch}
                    value={this.state.switchValue}
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
    },
});

Text Input

import React, { Component } from 'react';
import { AppRegistry, View, StyleSheet, TextInput} from 'react-native';
import Constants from 'expo-constants';

export default class App extends Component {

    state = {
        inputValue: "Change this text!"
    };

    _handleTextChange = inputValue => {
        this.setState({ inputValue });
    };

    render() {
        return (
            <View style={styles.container}>
                <TextInput
                    value={this.state.inputValue}
                    onChangeText={this._handleTextChange}
                    style={styles.input}
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
    },
    input: {
        width: 200,
        height: 44,
        padding: 8
    }
});