This episode covers the React Native core components: View, Text, Image, ImageBackground, TextInput, ScrollView, FlatList, and SectionList, plus styling with StyleSheet.create, Flexbox layout, gap, and the dp, px, and percentage units.

Every React Native app is an arrangement of core components. In episode 3 you created a project and saw App.tsx; now it's time to understand each basic component and how to arrange them until they look great.
Episode 4 dissects the core components one by one — View, Text, Image, TextInput, ScrollView, FlatList, and SectionList — then dives into the styling system: StyleSheet.create, Flexbox layout, the gap property, and the difference between the dp, px, and percentage units. These are the foundations you'll use in almost every later episode.
View is the building block of layout — similar to div on the web. Almost every layout element is wrapped in a View. Meanwhile, Text is the only way to display text. An important rule: text can't be placed directly inside a View; it must be inside a Text.
import { View, Text, StyleSheet } from "react-native";
export function Header() {
return (
<View style={styles.header}>
<Text style={styles.title}>Halo React Native</Text>
<Text style={styles.subtitle}>Seri belajar mobile</Text>
</View>
);
}Notice the pattern in the Header above: styles.header and styles.title refer to the object created by StyleSheet.create — we'll discuss that shortly.
Image displays an image, either from a network URL or a local asset. Don't forget to set the style with dimensions, because Image has no intrinsic size. ImageBackground is its sibling that can serve as a background with content on top of it.
TextInput is the input field. The two most important props: value and onChangeText. Since mobile has no physical keyboard, TextInput can also be configured with keyboardType, secureTextEntry for passwords, and placeholder.
ScrollView: scrolls content that's larger than the screen. Suitable for static content and small amounts of data.FlatList: a long-data list with virtualization — only visible elements are rendered.SectionList: like FlatList but supports grouped section headers.For data with hundreds of rows, always choose FlatList or SectionList, not ScrollView. Performance details are covered in episode 8.
StyleSheet.create provides style validation and value conversion at development time, plus easier organization. Inline styles with object literals are valid, but a large project quickly becomes messy without it.
import { StyleSheet } from "react-native";
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
gap: 12,
},
input: {
width: "80%",
height: 44,
borderWidth: 1,
borderColor: "#cccccc",
borderRadius: 8,
paddingHorizontal: 12,
},
});The styles above show several important things: flex: 1 makes the container fill all available space, gap: 12 creates spacing between children, and sizes use plain numbers (meaning dp) plus a percentage for the input width.
Flexbox is React Native's main layout system. Unlike web CSS, whose default is row, React Native uses flexDirection: "column" as the default. The most frequently used properties:
flexDirection: row, column, and their reverses.justifyContent: arranges along the main axis (for example center, space-between).alignItems: arranges along the cross axis.flex: controls the proportion of space an element takes.gap: spacing between children, reducing the need for manual margins.import { View, Text, StyleSheet } from "react-native";
export function MenuRow() {
return (
<View style={styles.row}>
<Text>Beranda</Text>
<Text>Profil</Text>
<Text>Pengaturan</Text>
</View>
);
}
const styles = StyleSheet.create({
row: { flexDirection: "row", gap: 16, alignItems: "center" },
});In React Native, all unitless numbers are treated as dp (density-independent pixel). One dp represents a size that's consistent across screens with different densities — a height of 44 looks physically the same on small and large screens. This is why you don't need to write px for dimensions.
width: "50%" takes half the parent's width.px unit in a string such as "1px".% for height: also supported, but flex is more often used to handle dynamic height.Rule of thumb: use dp for fixed sizes, percentages or flex for relative sizes, and avoid px except for thin borders.
Warning
Don't mix dp numbers and percentage strings carelessly. A style like height: "50" will fail because RN expects a number, not a string. Stay consistent with the types used in StyleSheet.create.
Text placed directly inside a View without a Text won't be rendered. Make sure every string is inside a Text component.
Layouts that look different between iOS and Android are usually caused by default fonts and the safe area. Use SafeAreaView or the safe-area-context library to handle notches. We'll revisit this during navigation in episode 6.
Episode 4 equipped you with the core toolkit for building screens: core components for content and input, styling with StyleSheet.create, Flexbox layout with gap, and an understanding of the dp, percentage, and px units.
Key takeaways:
View for layout, Text for text, Image for images.ScrollView for static content; FlatList and SectionList for long data.StyleSheet.create tidies up and validates styles.column, and gap reduces manual margins.flex are for relative sizes.In the next episode, episode 5, we'll discuss state, props, and hooks: useState, useEffect, useRef, useMemo, and useCallback, component composition patterns, and typing props with TypeScript — the heart of your app's interactive logic.