Lists with FlatList
You'll learn to show a long, scrolling list with FlatList, and to read its three main props.
Watch & read
Start with the required ones. The others are there when you need them.
See it step by step
FlatList renders a window of rows around the screen, not the whole list.
Explanation
You want to show every habit as a row, and the list must scroll when it gets longer than the screen. In
React on the web you used map. On a phone, a plain View does not scroll at all. You need a list
component.
Think of your phone's contacts app with 800 names. It does not draw all 800 at once. It draws the ones
on screen, plus a few above and below, and draws more as you scroll. FlatList works the same way. It
renders the rows near the screen and removes ones far away. That keeps long lists fast and saves memory.
<FlatListdata={habits}keyExtractor={(habit) => habit.id}renderItem={({ item }) => <Text>{item.name}</Text>}/>
datais your array.renderItemis a function that draws one row. FlatList calls it with an object, and your habit is inside it asitem. That is why you see({ item })with curly brackets. You also getindex.keyExtractorreturns a unique string for each row, like thekeyprop you used withmap. If you leave it out, FlatList looks foritem.key, thenitem.id, then uses the position.
A ScrollView with habits.map(...) inside also scrolls. It is fine for a short list that never grows,
like a settings page. But it renders every row at once, so use FlatList for anything that can get long.
People often write renderItem={(habit) => <Text>{habit.name}</Text>}. The argument is not the habit,
it is a wrapper { item, index }. habit.name is undefined, so every row is empty. Unpack it with
({ item }).
Two more props you'll meet: ListEmptyComponent shows something when data is empty ("No habits yet"),
and ItemSeparatorComponent draws a line between rows.
When you read a FlatList, find data first (what list?), then renderItem (what does one row look like?),
then keyExtractor (what makes each row unique?).
Code tour
Click a line number with a ring to read the note for that line.
Practice
Short drills. Take your time and read the code before you answer.
1const habits = [2 { id: "h1", name: "Drink water" },3 { id: "h2", name: "Read 10 pages" },4 { id: "h3", name: "Walk 20 minutes" },5];67export default function App() {8 return (9 <FlatList10 data={habits}11 renderItem={(habit) => <Text>{habit.name}</Text>}12 />13 );14}
toggle so it gives back a new array where only the tapped habit has done flipped. Then check the empty list message.1import { useState } from "react";2import { FlatList, Pressable, StyleSheet, Text, View } from "react-native";34const start = [5 { id: "h1", name: "Drink water", done: false },6 { id: "h2", name: "Read 10 pages", done: false },
Runs in the browser. Choose “My Device” in Snack to try it on your phone with Expo Go.
useState(start) to useState([]), the screen says "No habits yet."Quick check
3 questions. Each one explains itself after you answer.
- 1 / 3In
renderItem={({ item }) => ...}, what isitem? - 2 / 3Why use
FlatListinstead ofhabits.mapinside aScrollViewfor a long list? - 3 / 3Your habits look like
{ id: "h1", name: "Walk" }. What shouldkeyExtractorbe?
Explain it back
How confident are you with Lists with FlatList?
Done
FlatList and say what each row shows and which value is its key.