Working with Lists: FlatList
You could render a list with .map() like on the web, but for anything beyond a handful of items, React Native gives you FlatList, a component built specifically for large, scrollable lists.
Why not just .map()?
<ScrollView>
{courses.map((c) => <CourseRow key={c.id} course={c} />)}
</ScrollView>
This renders every single item immediately, for a list of 5 that's fine, for a list of 5,000 it tanks performance and memory. FlatList only renders what's currently visible on screen (plus a small buffer), recycling views as the user scrolls.
Basic usage
import { FlatList, Text, View } from 'react-native';
function CourseList({ courses }) {
return (
<FlatList
data={courses}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ padding: 12 }}>
<Text>{item.title}</Text>
</View>
)}
/>
);
}
datais the array to render.keyExtractoris FlatList's equivalent of thekeyprop, a function returning a unique string id per item.renderItemreceives{ item, index }and returns the JSX for a single row.
Useful extras
<FlatList
data={courses}
keyExtractor={(item) => item.id}
renderItem={renderCourse}
ListEmptyComponent={<Text>No courses yet.</Text>}
ListHeaderComponent={<Text>All Courses</Text>}
onEndReached={loadMoreCourses}
onEndReachedThreshold={0.5}
refreshing={isRefreshing}
onRefresh={reloadCourses}
/>
onEndReached fires when the user scrolls near the bottom, the standard hook for infinite scroll/pagination. refreshing/onRefresh wire up the native pull-to-refresh gesture for free.
WARNING
Never nest a FlatList inside a ScrollView that scrolls in the same direction, both will try to own scrolling and you'll get janky, broken behavior. If you need multiple lists on one screen, give FlatList a fixed height or use ListHeaderComponent/ListFooterComponent to add content around a single list instead.