FlatList: какво е, API и оптимизация в React Native

Автор: IT Sectr Публикувано: 2026-07-05 Време за четене: 10 мин

FlatList — основният компонент на React Native за показване на производителни списъци с виртуализация на елементи. За разлика от ScrollView, FlatList рендерира само видимите елементи на екрана, спестявайки памет и процесор. Компонентът поддържа хоризонтално и вертикално превъртане, pull-to-refresh и безкрайно зареждане. Повече за архитектурата на списъците прочетете в документацията на Meta.

Основни точки

  • FlatList — виртуализиран компонент за списък, който рендерира само видимите елементи и ги преизползва при превъртане
  • Производителност се постига чрез прозоречно рендериране (windowing) — елементите извън екрана не се създават
  • API включва renderItem, keyExtractor, ItemSeparatorComponent, ListHeaderComponent и ListFooterComponent
  • Хоризонтални списъци се конфигурират чрез флага horizontal и променят посоката на превъртане към ос X
  • Оптимизация изисква правилно конфигуриране на keyExtractor, useMemo за данни и getItemLayout за фиксирани размери

Какво е FlatList?

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

Виртуализация на FlatList — механизъм, при който компонентът рендерира само елементите, които се намират във видимата област на екрана, плюс малък буфер от всяка страна. Останалите елементи не се създават в DOM, което спестява памет и ускорява рендерирането.

При превъртане, FlatList преизползва вече създадени View клетки, като заменя данните в тях. Това предотвратява създаването на хиляди View за списък от 10 000 елемента. Размерът на буфера по подразбиране е 10 елемента над и под видимата област, но може да се конфигурира чрез windowSize.

ПараметърПо подразбиранеОписание
windowSize21Брой страници за рендериране (1 страница = височина на екрана)
initialNumToRender10Брой елементи при първото рендериране
maxToRenderPerBatch10Максимум елементи, рендерирани в една партида
removeClippedSubviewsfalseПремахване на View извън екрана от йерархията

Оптималното конфигуриране на тези параметри позволява балансиране между плавността на превъртане и консумацията на памет. За списъци с големи елементи се препоръчва намаляване на windowSize до 5-7.

API и основни пропсове на FlatList

API на FlatList включва набор от пропсове за конфигуриране на външния вид и поведението на списъка. Два задължителни пропса — data (масив от данни) и renderItem (функция за рендериране на елемент). keyExtractor повишава производителността, като предоставя уникален ключ за всеки елемент.

js
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 — заглавна и долна част на списъка. Това позволява създаване на сложни оформления без допълнителна обвивка.

js
const styles = StyleSheet.create({
  item: {
    padding: 16,
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    borderBottomColor: '#e0e0e0',
  },
  separator: {
    height: 1,
    backgroundColor: '#ccc',
  },
});

Оптимизация на производителността на FlatList

Оптимизация на FlatList е критично важна за приложения със стотици и хиляди елементи. Без правилно конфигуриране, списъкът може да забавя при превъртане, да консумира прекомерна памет и да причинява сривове на слаби устройства.

Първо правило — използвайте keyExtractor с уникални и стабилни идентификатори. Индексите като ключове водят до неправилно преизползване на клетки и грешки в състоянието. Второ — обвийте renderItem в useCallback и използвайте React.memo за компонента на елемента.

getItemLayout за фиксирана височина

Ако всички елементи имат еднаква височина, getItemLayout позволява на FlatList да изчислява позицията на превъртане без измерване на компоненти. Това дава значително увеличение на производителността, особено при превъртане до определен индекс.

js
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 за стъпково превъртане, както в нативните карусели. Компонентът автоматично обработва инерцията и отпускането на пръста, спирайки на най-близкия елемент.

js
<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 и безкрайно зареждане

Pull-to-refresh в FlatList се имплементира чрез пропсовете refreshing и onRefresh, които работят заедно със състоянието на зареждане. При издърпване на списъка надолу се извиква onRefresh, а флагът refreshing блокира повторни извиквания.

Безкрайно зареждане (infinite scroll) се конфигурира чрез onEndReached — callback, който се задейства при приближаване до края на списъка. onEndReachedThreshold определя колко елемента преди края задейства събитието. За пагинация обикновено се използва cursor-based подход.

js
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?

FlatList използва виртуализация — рендерира само видимите елементи, което спестява памет при големи данни. ScrollView рендерира всички дъщерни елементи наведнъж, подходящ само за малки списъци до 20-30 елемента. FlatList е оптимален за 100+ елемента.

Как да поправим мигане (flash) при обновяване на данните на FlatList?

Мигането възниква при промяна на референцията на масива data. Използвайте extraData, предавайки зависимостта там, или обвийте renderItem в React.memo. За пълен контрол приложете useMemo за стабилизиране на референциите на данните.

Защо FlatList не се превърта вътре в друг scroll-view?

FlatList не е предназначен за влагане в ScrollView поради конфликт на жестове. Решения: използвайте FlatList с nestedScrollEnabled (Android), SectionList за секции или изнесете външното превъртане в FlatList чрез ListHeaderComponent.

Как да анимираме появата на елементите на FlatList?

Използвайте Animated API вътре в renderItem със закъснение на базата на индекса. При превъртане приложете onViewableItemsChanged за задействане на анимация. Библиотеките react-native-reanimated и react-native-lottie опростяват създаването на сложни анимации на поява.

Какво е VirtualizedList и как е свързан с FlatList?

VirtualizedList — основният компонент за виртуализация, върху който са изградени FlatList и SectionList. FlatList е обвивка на VirtualizedList с опростен API за плоски списъци. VirtualizedList предоставя по-ниско ниво на контрол, но рядко се използва директно.

Обобщение

  • FlatList — основният компонент на React Native за производителни списъци с автоматична виртуализация и преизползване на клетки
  • Виртуализация рендерира само видимите елементи чрез windowSize и initialNumToRender, спестявайки памет на големи набори от данни
  • Задължителни пропсове: data, renderItem и keyExtractor — осигуряват правилната работа на списъка
  • getItemLayout ускорява превъртането за елементи с фиксирана височина, елиминирайки динамичното измерване
  • Хоризонтални списъци и карусели се конфигурират чрез horizontal и snapToInterval за стъпково превъртане
  • Pull-to-refresh и onEndReached имплементират безкрайно зареждане със защита от повторни извиквания
  • React.memo и useCallback са задължителни за renderItem — без тях всяко превъртане причинява повторно рендериране на всички елементи

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също