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

Автор: IT Sectr Опубліковано: 2026-07-05 Час читання: 10 хв

FlatList — основний компонент React Native для відображення продуктивних списків із віртуалізацією елементів. На відміну від ScrollView, FlatList рендерить лише видимі елементи екрана, економлячи пам'ять і процесор. Компонент підтримує горизонтальне та вертикальне прокручування, pull-to-refresh і нескінченне завантаження. Докладніше про архітектуру списків читайте в документації Meta.

Головне

  • FlatList — віртуалізований компонент списку, який рендерить лише видимі елементи та перевикористовує їх під час скролу
  • Продуктивність досягається завдяки віконному рендерингу — елементи за межами екрана не створюються
  • 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

FlatList API включає набір пропсів для налаштування відображення та поведінки списку. Два обов'язкові пропси — 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 — колбек, що викликається при зміні видимих елементів. Використовується для аналітики, лінивого завантаження зображень та активації відео лише для видимих карток.

Pull-to-refresh і нескінченне завантаження

Pull-to-refresh у FlatList реалізується через пропси refreshing та onRefresh, що працюють у парі зі станом завантаження. При потягуванні списку вниз викликається onRefresh, а прапорець refreshing блокує повторні виклики.

Нескінченне завантаження налаштовується через onEndReached — колбек, що спрацьовує при наближенні до кінця списку. 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 не скролиться всередині іншого скрол-в'ю?

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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також