FlatList — основни React Native компонент за приказ продуктивних листа са виртуелизацијом елемената. За разлику од ScrollView, FlatList рендерује само видљиве елементе екрана, штедећи меморију и процесор. Компонент подржава хоризонтално и вертикално скроловање, pull-to-refresh и бесконачно учитавање. Више о архитектури листа прочитајте у Meta документацији.
Главне тачке
FlatList — React Native компонент који имплементира виртуелизовану листу са продуктивним рендеровањем великих количина података. Компонент је изграђен на бази VirtualizedList и пружа декларативни API за креирање равних листа било које сложености.
FlatList се појавио у React Native 0.43 као замена за застарели ListView. Према Meta подацима (2026), FlatList се користи у 85% React Native апликација које раде са листама. Компонент подржава све уобичајене сценарије: контакте, вести феедове, каталоге производа, ћаскања.
Пре појаве FlatList, програмери су користили ListView, који је захтевао ручно подешавање поновне употребе ћелија. FlatList је аутоматизовао овај процес, уводећи прозорско рендеровање слично RecyclerView у Android-у (2014) и UICollectionView у iOS-у (2012). У модерним пројектима, FlatList је дефакто стандард за све листе.
Виртуелизација FlatList — механизам у ком компонент рендерује само елементе који се налазе у видљивом делу екрана, плус мали бафер са сваке стране. Остали елементи се не креирају у DOM-у, што штеди меморију и убрзава рендеровање.
При скроловању, FlatList поново користи већ креиране View ћелије, замењујући податке у њима. Ово спречава креирање хиљада View-ова за листу од 10 000 елемената. Подразумевана величина бафера је 10 елемената изнад и испод видљивог подручја, али се може подесити преко windowSize.
| Параметар | Подразумевано | Опис |
|---|---|---|
| windowSize | 21 | Број страница за рендеровање (1 страница = висина екрана) |
| initialNumToRender | 10 | Број елемената при првом рендеру |
| maxToRenderPerBatch | 10 | Максимум елемената рендерованих у једној серији |
| removeClippedSubviews | false | Уклањање View-ова ван екрана из хијерархије |
Оптимално подешавање ових параметара омогућава балансирање између глаткоће скроловања и потрошње меморије. За листе са великим елементима препоручује се смањење windowSize на 5-7.
FlatList API укључује скуп пропсова за подешавање изгледа и понашања листе. Два обавезна пропса — data (низ података) и renderItem (функција рендеровања елемента). keyExtractor повећава перформансе пружајући јединствени кључ за сваки елемент.
import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
const App = () => {
const data = Array.from({ length: 100 }, (_, i) => ({
id: i.toString(),
title: `Item #${i + 1}`,
}));
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
);
};ItemSeparatorComponent додаје раздвајач између елемената, ListHeaderComponent и ListFooterComponent — заглавље и подножје листе. Ово омогућава креирање сложених распореда без додатног омотача.
const styles = StyleSheet.create({
item: {
padding: 16,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
separator: {
height: 1,
backgroundColor: '#ccc',
},
});Оптимизација FlatList је критично важна за апликације са стотинама и хиљадама елемената. Без правилног подешавања, листа може да успори при скроловању, троши прекомерну меморију и изазива падове на слабијим уређајима.
Прво правило — коришћење keyExtractor са јединственим и стабилним идентификаторима. Индекси као кључеви доводе до нетачног поновног коришћења ћелија и грешака у стању. Друго — умотавање renderItem у useCallback и коришћење React.memo за компонент елемента.
Ако сви елементи имају исту висину, getItemLayout омогућава FlatList-у да израчуна позицију скроловања без мерења компонената. Ово даје значајан пораст перформанси, посебно при скроловању до одређеног индекса.
const ITEM_HEIGHT = 80;
const getItemLayout = (data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
});
<FlatList
data={data}
getItemLayout={getItemLayout}
renderItem={renderItem}
/FlatList>useMemo за податке спречава непотребна поновна рендеровања. Ако подаци долазе из API-ја, обрадите их једном и кеширајте. Користите React.memo за компонент елемента да бисте избегли рендеровање непромењених елемената.
Хоризонтални FlatList се креира додавањем пропса horizontal={true}. Листа мења правац скроловања на осу X, што је згодно за каруселе производа, галерије слика и хоризонталне меније.
У хоризонталном режиму важно је правилно подесити snapToInterval и snapToAlignment за корачно скроловање, као у изворним каруселима. Компонент аутоматски обрађује момент и пуштање прста, заустављајући се на најближем елементу.
<FlatList
horizontal
data={images}
renderItem={renderItem}
keyExtractor={item => item.id}
showsHorizontalScrollIndicator={false}
snapToInterval={CARD_WIDTH + GAP}
snapToAlignment="start"
decelerationRate="fast"
pagingEnabled
onViewableItemsChanged={onViewableItemsChanged}
/>onViewableItemsChanged — callback који се позива при промени видљивих елемената. Користи се за аналитику, лењо учитавање слика и активирање видеа само за видљиве картице.
Pull-to-refresh у FlatList-у се имплементира преко пропсова refreshing и onRefresh, који раде у пару са стањем учитавања. При повлачењу листе наниже позива се onRefresh, а флаг refreshing блокира поновне позиве.
Бесконачно учитавање (infinite scroll) се подешава преко onEndReached — callback-а који се активира при приближавању крају листе. onEndReachedThreshold одређује колико елемената пре краја активира догађај. За пагинацију се обично користи cursor-based приступ.
const ListWithPagination = () => {
const [data, setData] = React.useState([]);
const [page, setPage] = React.useState(1);
const [refreshing, setRefreshing] = React.useState(false);
const loadMore = React.useCallback(async () => {
const newData = await fetchPage(page);
setData(prev => [...prev, ...newData]);
setPage(p => p + 1);
}, [page]);
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
refreshing={refreshing}
onRefresh={loadMore}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
/>
);
};Важно: onEndReached се може позвати више пута. Додајте флаг isLoading за блокирање поновних захтева док се претходни не заврши. Користите ActivityIndicator у ListFooterComponent за приказ учитавања.
Често постављана питања
FlatList користи виртуелизацију — рендерује само видљиве елементе, што штеди меморију код великих података. ScrollView рендерује све подређене елементе одједном, погодан само за мале листе до 20-30 елемената. FlatList је оптималан за 100+ елемената.
Трептање настаје при промени референце низа data. Користите extraData, преносећи зависност тамо, или умотајте renderItem у React.memo. За потпуну контролу примените useMemo за стабилизацију референци података.
FlatList није намењен за уметање у ScrollView због конфликта гестова. Решења: користите FlatList са nestedScrollEnabled (Android), SectionList за секције или изнесите спољашње скроловање у FlatList преко ListHeaderComponent.
Користите Animated API унутар renderItem-а са кашњењем на основу индекса. При скроловању примените onViewableItemsChanged за покретање анимације. Библиотеке react-native-reanimated и react-native-lottie поједностављују креирање сложених анимација појављивања.
VirtualizedList — основни компонент виртуелизације на ком су изграђени FlatList и SectionList. FlatList је омотач VirtualizedList-а са поједностављеним API-јем за равне листе. VirtualizedList пружа контролу нижег нивоа, али се ретко користи директно.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође