Bootcamp
Search…
📅
Course Schedule
0: Language and Tooling Teaching Guide
1: Frontend Basics Teaching Guide
2: Backend Basics Teaching Guide
3: Backend Applications Teaching Guide
4: Backend Structure Teaching Guide
5: Full-Stack Applications Teaching Guide
6: Frontend Infrastructure Teaching Guide
7: React Teaching Guide
8: Advanced React Teaching Guide
9: Advanced Topics Teaching Guide
🧮
Algorithms Teaching Guide
💼
Interview Prep Teaching Guide
☺
User Experience Teaching Guide
9.4: React Native

Introduction

React native is a system that uses javascript and React syntax to render mobile "native" components inside a mobile device.
In any UI system there is a system of conceptual components that the programmer can put on the screen and write interactions for.
React Native is a library that wraps around a set of those that are available in iOS and Android so that developers can write React JavaScript but run their equivalent Android / iOS components on a phone or tablet.

Setup

React Native comes with it's own development environment to make it easier to write an app and interface with the native mobile build tools, i.e., XCode / Android Studio.
1
npm install -g expo-cli
Copied!
Init the expo project. Choose managed blank workflow.
1
expo init rocketTodo
2
​
3
cd rocketTodo
4
npm start # you can also use: expo start
Copied!

Windows Setup

Expo uses a special ngrok wrapper so that WSL2 can be accessed from outside localhost.
Install it globally in WSL:
1
sudo npm install -g @expo/ngrok
Copied!
Start expo with a different command than above:
1
expo start --tunnel
Copied!

Components

The key React components listed here have their own analogs in Android and iOS.
<View>
<ViewGroup>
<UIView>
A non-scrollling <div>
A container that supports layout with flexbox, style, some touch handling, and accessibility controls
<Text>
<TextView>
<UITextView>
<p>
Displays, styles, and nests strings of text and even handles touch events
<Image>
<ImageView>
<UIImageView>
<img>
Displays different types of images
<ScrollView>
<ScrollView>
<UIScrollView>
<div>
A generic scrolling container that can contain multiple components and views
<TextInput>
<EditText>
<UITextField>
<input type="text">
Allows the user to enter text

Example: Todo List

As an example we'll write a todo list. Note how similar this code is to Browser React.

Dependencies

Icons

We want to display a few nice icons like a checkbox and trash can.
1
npm install react-native-vector-icons
Copied!

Storage

We can easily add a library that will save our list for the next time the user opens the app.
1
npm install @react-native-async-storage/async-storage
Copied!

App

App.js

1
import React, { useState, useEffect, useRef } from 'react';
2
import {
3
Text,
4
View,
5
TextInput,
6
TouchableOpacity,
7
ScrollView,
8
} from 'react-native';
9
import Icon from 'react-native-vector-icons/Feather';
10
import AsyncStorage from '@react-native-async-storage/async-storage';
11
import { styles } from './styles';
12
const MY_RA_TODO_APP_KEY = 'my-ra-todo-app-key';
13
​
14
const Task = (props) => (
15
<View style={styles.taskWrapper}>
16
<TouchableOpacity onPress={() => props.setChecked()}>
17
<Icon
18
name={props.checked ? 'check' : 'square'}
19
size={30}
20
color="#900"
21
style={{ marginLeft: 15 }}
22
/>
23
</TouchableOpacity>
24
​
25
<View>
26
{props.checked && <View style={styles.verticalLine}></View>}
27
<Text style={styles.task}>{props.text}</Text>
28
</View>
29
<Icon
30
name="trash-2"
31
size={30}
32
color="#900"
33
style={{ marginLeft: 'auto', marginRight: 10 }}
34
onPress={props.delete}
35
/>
36
</View>
37
);
38
​
39
export default function App() {
40
const [value, setValue] = useState('');
41
const [todos, setTodos] = useState([]);
42
​
43
const isInitialMount = useRef(true); //useEffect to run only on updates except initial mount
44
​
45
useEffect(() => {
46
if (isInitialMount.current) {
47
// get it from async storage
48
AsyncStorage.getItem(MY_RA_TODO_APP_KEY).then((storedData) => {
49
const storedDataParsed = JSON.parse(storedData) || [];
50
​
51
setTodos(storedDataParsed);
52
isInitialMount.current = false;
53
});
54
} else {
55
// update async storage
56
AsyncStorage.setItem(MY_RA_TODO_APP_KEY, JSON.stringify(todos));
57
}
58
}, [todos]);
59
​
60
const handleAddTodo = () => {
61
if (value.length > 0) {
62
setTodos([...todos, { text: value, key: Date.now(), checked: false }]);
63
setValue('');
64
}
65
};
66
​
67
const handleDeleteTodo = (id) => {
68
setTodos(
69
todos.filter((todo) => {
70
if (todo.key !== id) return true;
71
})
72
);
73
};
74
​
75
const handleChecked = (id) => {
76
setTodos(
77
todos.map((todo) => {
78
if (todo.key === id) todo.checked = !todo.checked;
79
return todo;
80
})
81
);
82
};
83
return (
84
<View style={styles.container}>
85
<Text style={{ marginTop: '10%', fontSize: 16, color: 'white' }}>
86
Rocket List
87
</Text>
88
<View style={styles.textInputContainer}>
89
<TextInput
90
style={styles.textInput}
91
onChangeText={(value) => setValue(value)}
92
placeholder={'Do it now!'}
93
value={value}
94
/>
95
<TouchableOpacity onPress={() => handleAddTodo()}>
96
<Icon name="plus" size={30} color="#900" />
97
</TouchableOpacity>
98
</View>
99
<ScrollView style={styles.scroll}>
100
{todos.map((task) => (
101
<Task
102
text={task.text}
103
key={task.key}
104
checked={task.checked}
105
setChecked={() => handleChecked(task.key)}
106
delete={() => handleDeleteTodo(task.key)}
107
/>
108
))}
109
</ScrollView>
110
</View>
111
);
112
}
Copied!

styles.js

1
import { StyleSheet } from 'react-native';
2
​
3
export const styles = StyleSheet.create({
4
container: {
5
flex: 1,
6
alignItems: 'center',
7
backgroundColor: '#474747',
8
},
9
textInput: {
10
height: 20,
11
flex: 1,
12
minHeight: '7%',
13
marginTop: '5%',
14
fontSize: 25,
15
fontWeight: 'bold',
16
color: '#ffffff',
17
paddingLeft: 10,
18
},
19
textInputContainer: {
20
justifyContent: 'center',
21
backgroundColor: '#ffffff',
22
flexDirection: 'row',
23
alignItems: 'center',
24
borderColor: 'rgb(222,222,222)',
25
borderBottomWidth: 1,
26
padding: 10,
27
},
28
textInput: {
29
padding: 5,
30
marginRight: 5,
31
backgroundColor: '#ffffff',
32
},
33
taskWrapper: {
34
marginTop: '5%',
35
flexDirection: 'row',
36
borderColor: '#ffffff',
37
borderBottomWidth: 1.5,
38
alignItems: 'center',
39
minHeight: 40,
40
margin: 10,
41
justifyContent: 'space-between',
42
},
43
task: {
44
paddingBottom: 12,
45
paddingLeft: 10,
46
marginTop: 6,
47
marginBottom: 3,
48
fontSize: 13,
49
fontWeight: 'bold',
50
color: '#ffffff',
51
},
52
verticalLine: {
53
borderBottomColor: '#ffffff',
54
borderBottomWidth: 2,
55
marginLeft: 10,
56
width: '100%',
57
position: 'absolute',
58
marginTop: 15,
59
},
60
});
Copied!
See a working demo here:

Further Reading

Official Docs: https://reactnative.dev/​

Use Jest for React Native Testing

We recommend using Jest for React Native testing instead of Mocha and Chai. Jest is a newer alternate testing library to Mocha and Chai that has similar features but is developed by Facebook and works more seamlessly with React and React Native. See docs on how to test with Jest here: https://docs.expo.io/guides/testing-with-jest/​
Last modified 2mo ago