React Native Basics: Build Your First Mobile App
Core Components
In this lesson you will
- Build a screen from View, Text, Image and ScrollView
- Explain why all text must be inside a Text component
- Use Pressable for buttons and TextInput for typing
Introduction
On the web you build pages from HTML tags such as div, p and img. In React Native there are no HTML tags. Instead you import a small set of core components from "react-native". They are the building blocks of every screen, and most apps use only a handful of them.
View: the container
View is the box you put other things in. It is like a div that does not scroll. You use it to group items and to lay them out with flexbox, which the next lesson covers.
React (TSX)
import { View, Text } from "react-native";
export default function Card() {
return (
<View>
<Text>Inside a View</Text>
</View>
);
}Text: all words go here
The most surprising rule for web developers: every piece of text must be inside a Text component. Writing words directly inside a View is an error.
React (TSX)
import { Text, View } from "react-native";
export default function Greeting() {
return (
<View>
<Text>
Hello, <Text style={{ fontWeight: "bold" }}>world</Text>
</Text>
</View>
);
}You can nest Text inside Text, as above, to style part of a sentence. A nested Text inherits the style of its parent. This is one of the few places where styles are inherited. Elsewhere in React Native, a style on a View does not pass down to its children, unlike CSS.
Quick quiz
Where must the words in a React Native screen go?
Image: pictures
Image shows a picture. A picture bundled with your app is loaded with require and a path relative to the file you are writing in (here, a file called cat.png beside it). A picture from the internet is given as an object with a uri.
React (TSX)
import { Image, StyleSheet, View } from "react-native";
export default function Pictures() {
return (
<View>
<Image source={require("./cat.png")} style={styles.local} />
<Image source={{ uri: "https://reactnative.dev/img/tiny_logo.png" }} style={styles.remote} />
</View>
);
}
const styles = StyleSheet.create({
local: { width: 64, height: 64 },
remote: { width: 64, height: 64 },
});Notice the width and height. A picture loaded from the internet has no size until it arrives, so React Native cannot work it out for you. Always give network images a width and height, or they will not show.
ScrollView: content that scrolls
A View does not scroll. When content is taller than the screen, wrap it in a ScrollView.
React (TSX)
import { ScrollView, Text } from "react-native";
export default function LongPage() {
return (
<ScrollView>
<Text>Paragraph one</Text>
<Text>Paragraph two</Text>
<Text>Paragraph three</Text>
</ScrollView>
);
}ScrollView builds all its children at once, which is fine for a short page but wasteful for a long list of hundreds of items. A later lesson shows the better tool for long lists, FlatList.
TextInput: typing
TextInput is a box where the user types. It is like an HTML input. You will connect it to state in the lesson after next. Useful props already:
React (TSX)
import { TextInput } from "react-native";
export default function EmailBox() {
return (
<TextInput
placeholder="[email protected]"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
/>
);
}keyboardType chooses which keyboard appears, such as numbers or email, and autoCapitalize="none" stops the phone from capitalising the first letter.
Pressable: anything you can tap
To make something respond to a tap, use Pressable. Put whatever you like inside it, and give it an onPress function. This is the component to use for your own buttons, because you control how they look.
React (TSX)
import { Pressable, StyleSheet, Text } from "react-native";
export default function LikeButton() {
return (
<Pressable
onPress={() => console.log("Liked")}
style={({ pressed }) => [styles.button, pressed && styles.pressed]}
>
<Text style={styles.label}>Like</Text>
</Pressable>
);
}
const styles = StyleSheet.create({
button: { backgroundColor: "#5b4bf5", padding: 12, borderRadius: 8 },
pressed: { opacity: 0.6 },
label: { color: "white", fontWeight: "bold" },
});The style prop can be a function. It receives an object with pressed, which is true while a finger is down, so the button can dim while pressed. React Native also has a ready-made Button component, but it has limited styling and looks different on each phone. Most apps use Pressable for their own design.
Quick quiz
Why must a network Image be given a width and height?
Putting it together
Here is a small profile screen using everything so far:
React (TSX)
import { Image, Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
export default function Profile() {
return (
<ScrollView contentContainerStyle={styles.page}>
<Image source={{ uri: "https://reactnative.dev/img/tiny_logo.png" }} style={styles.avatar} />
<Text style={styles.name}>Ada Lovelace</Text>
<Text style={styles.bio}>Wrote the first computer program, long before there were computers to run it.</Text>
<Pressable style={styles.button} onPress={() => console.log("Follow")}>
<Text style={styles.buttonText}>Follow</Text>
</Pressable>
</ScrollView>
);
}
const styles = StyleSheet.create({
page: { alignItems: "center", padding: 24 },
avatar: { width: 96, height: 96, borderRadius: 48 },
name: { fontSize: 22, fontWeight: "bold", marginTop: 12 },
bio: { textAlign: "center", marginTop: 8, color: "#555" },
button: { marginTop: 16, backgroundColor: "#5b4bf5", paddingVertical: 10, paddingHorizontal: 24, borderRadius: 8 },
buttonText: { color: "white", fontWeight: "bold" },
});Try it yourself
Replace the text on your home screen with this profile. Change the name and bio, then add a second Pressable that logs a different message. Check the terminal: console.log output from your phone appears there.
Summary
- A screen is built from core components imported from
"react-native":View,Text,Image,ScrollView,TextInputandPressable. - All text must be inside
Text, network images need a width and height, andScrollViewis for short scrolling content. - Use
Pressablefor your own tappable buttons, with its style function to show a pressed state.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.