Lists and Virtualization
Virtualized lists for long data sets - FlatList, SectionList, and the knobs that keep scroll smooth.
Busque em todas as páginas da documentação
Virtualized lists for long data sets - FlatList, SectionList, and the knobs that keep scroll smooth.
data, renderItem, and a stable keyExtractor are the minimum. Prefer string ids over indexes.
import { FlatList, Text } from "react-native";
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>Render dividers between items without putting borders on every row.
const Separator = () => <View style={{ height: 1, backgroundColor: "#e5e7eb" }} />;
<FlatList ItemSeparatorComponent={Separator} data={items} renderItem={...} />Show a dedicated empty state when data is empty (and not loading).
<FlatList
data={items}
ListEmptyComponent={<Text>No results</Text>}
renderItem={...}
/>Headers and footers scroll with the list (or stick with sticky header indices when configured).
<FlatList
ListHeaderComponent={<SearchBar />}
ListFooterComponent={loadingMore ? <ActivityIndicator /> : null}
data={items}
renderItem={...}
/>Same RefreshControl pattern as ScrollView, via refreshing / onRefresh props or refreshControl.
<FlatList
data={items}
refreshing={refreshing}
onRefresh={onRefresh}
renderItem={...}
/>Load the next page when the user approaches the end. Guard with a loading flag to avoid duplicate fetches.
<FlatList
data={items}
onEndReached={() => {
if (!loadingMore && hasMore) loadMore();
}}
onEndReachedThreshold={0.4}
renderItem={...}
/>Set numColumns for simple grids. Item width should account for columns and gaps.
<FlatList
data={photos}
numColumns={3}
keyExtractor={(p) => p.id}
renderItem={({ item }) => <Thumb photo={item} />}
/>Sectioned data needs sections with { title, data } entries and section header renderers.
import { SectionList, Text } from "react-native";
<SectionList
sections={sections}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Text>{item.name}</Text>}
renderSectionHeader={({ section }) => <Text>{section.title}</Text>}
/>When every row has a known height, provide getItemLayout so scroll-to-index skips measurement.
const H = 56;
getItemLayout={(_, index) => ({ length: H, offset: H * index, index })}FlatList pure-renders from data. Pass extraData when selection state outside data should re-render rows.
<FlatList data={items} extraData={selectedId} renderItem={renderItem} />Extract rows and wrap with React.memo so unchanged items skip work when the parent re-renders.
const Row = memo(function Row({ item }: { item: Item }) {
return <Text>{item.title}</Text>;
});Control how many items render on first paint. Higher values reduce blank space; lower values speed TTI.
<FlatList initialNumToRender={12} data={items} renderItem={...} />windowSize is a multiplier of the viewport for offscreen rendering. Lower values save memory; higher values reduce blank scroll.
<FlatList windowSize={7} data={items} renderItem={...} />On Android, clipping offscreen views can improve memory. Test carefully with sticky headers and absolute children.
<FlatList removeClippedSubviews data={items} renderItem={...} />For very large lists, Shopify FlashList recycles cells more aggressively than FlatList. Same data/render mental model; different performance characteristics - adopt when FlatList profiling shows jank.
// import { FlashList } from "@shopify/flash-list";
// <FlashList data={items} estimatedItemSize={56} renderItem={...} />Stack versions: React 19.2.3 · React Native 0.86.0 · Expo SDK 57
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026