Что такое FlatList и в каких случаях её стоит использовать?

FlatList — это встроенный компонент React Native, предназначенный для эффективного отображения больших списков данных. Он оптимизирован для производительности и заменяет менее производительные способы отображения массивов элементов, такие как обычный ScrollView с мапом (.map()).

Что делает FlatList особенным

Обычные способы отрисовки списков, например через ScrollView с перебором массива элементов, подходят только для коротких списков. При больших объемах данных (сотни и тысячи элементов) они:

  • замедляют работу приложения;

  • загружают в память сразу весь список;

  • могут вызвать сбои из-за переполнения памяти.

FlatList, напротив, реализует ленивую подгрузку (виртуализацию): он рендерит только те элементы, которые находятся на экране, плюс небольшой буфер (offscreen render). Это значительно повышает производительность и снижает нагрузку на память.

Импорт

import { FlatList } from 'react-native';

Основные props FlatList

Вот базовые свойства, которые чаще всего используются при работе с FlatList:

Prop Описание
data Массив данных, из которых строится список.
--- ---
renderItem Функция, возвращающая JSX-элемент для каждого элемента списка.
--- ---
keyExtractor Функция, возвращающая уникальный ключ (string) для каждого элемента.
--- ---
ItemSeparatorComponent Компонент-разделитель между элементами.
--- ---
ListHeaderComponent Компонент, отображаемый в начале списка.
--- ---
ListFooterComponent Компонент, отображаемый в конце списка.
--- ---
onEndReached Функция, вызываемая при достижении конца списка (например, для подгрузки данных).
--- ---
refreshing Булево значение: показывает, активна ли операция обновления.
--- ---
onRefresh Колбэк для действия pull-to-refresh.
--- ---
initialNumToRender Количество элементов, которые будут отрисованы при первом рендере.
--- ---
horizontal Отображать ли список по горизонтали (по умолчанию — по вертикали).
--- ---

Простой пример FlatList

import React from 'react';
import { FlatList, Text, View } from 'react-native';
const DATA = \[
{ id: '1', title: 'Элемент 1' },
{ id: '2', title: 'Элемент 2' },
{ id: '3', title: 'Элемент 3' },
\];
export default function App() {
return (
<FlatList
data={DATA}
renderItem={({ item }) => (
&lt;View&gt;
&lt;Text&gt;{item.title}&lt;/Text&gt;
&lt;/View&gt;
)}
keyExtractor={item => item.id}
/>
);
}

Как работает renderItem

Проп renderItem принимает функцию, которая получает объект:

{
item, // текущий элемент массива
index, // индекс элемента
separators // методы управления разделителями (реже используется)
}
Пример с индексом:
renderItem={({ item, index }) => (
&lt;Text&gt;{index + 1}. {item.title}&lt;/Text&gt;
)}

keyExtractor

Чтобы React мог правильно идентифицировать элементы при изменении списка (например, при удалении или вставке), каждому элементу нужен уникальный key.

keyExtractor={(item) => item.id}

Если id нет, можно использовать index, но это не рекомендуется, особенно при динамических списках.

Pull-to-refresh

<FlatList
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
refreshing={isRefreshing}
onRefresh={handleRefresh}
/>
  • refreshing — булевый флаг, отображает индикатор загрузки сверху.

  • onRefresh — функция, вызываемая при жесте "потяни вниз, чтобы обновить".

Подгрузка при скролле (infinite scroll)

<FlatList
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
/>
  • onEndReached вызывается, когда пользователь скроллит близко к концу списка.

  • onEndReachedThreshold (значение от 0 до 1) — насколько близко к концу нужно дойти, чтобы сработал триггер (например, 0.5 — на 50%).

Добавление заголовка, футера и разделителей

<FlatList
data={data}
renderItem={renderItem}
ListHeaderComponent={&lt;Text&gt;Заголовок&lt;/Text&gt;}
ListFooterComponent={&lt;Text&gt;Конец списка&lt;/Text&gt;}
ItemSeparatorComponent={() => &lt;View style={{ height: 1, backgroundColor: '#ccc' }} /&gt;}
/>

Горизонтальный список

Для отображения элементов в строку:

<FlatList
horizontal
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
/>

Можно настроить отступы, выравнивание и т.п. через contentContainerStyle или ItemSeparatorComponent.

Стилизация

FlatList принимает стиль через style и contentContainerStyle:

<FlatList
style={{ flex: 1 }}
contentContainerStyle={{ padding: 10 }}
...
/>
  • style применяется к самому списку (например, flex: 1)

  • contentContainerStyle — к обёртке, содержащей все элементы

Пример с динамической подгрузкой и обновлением

import React, { useState, useEffect } from 'react';
import { FlatList, Text, View, ActivityIndicator, Button } from 'react-native';
function MyList() {
const \[data, setData\] = useState(\[\]);
const \[page, setPage\] = useState(1);
const \[refreshing, setRefreshing\] = useState(false);
const \[loadingMore, setLoadingMore\] = useState(false);
useEffect(() => {
fetchData();
}, \[page\]);
const fetchData = async () => {
const newData = await getItemsFromAPI(page); // заглушка
setData(prev => page === 1 ? newData : \[...prev, ...newData\]);
};
const onRefresh = () => {
setRefreshing(true);
setPage(1);
setRefreshing(false);
};
const onEndReached = () => {
if (!loadingMore) {
setLoadingMore(true);
setPage(prev => prev + 1);
setLoadingMore(false);
}
};
return (
<FlatList
data={data}
renderItem={({ item }) => &lt;Text&gt;{item.name}&lt;/Text&gt;}
keyExtractor={(item) => item.id.toString()}
refreshing={refreshing}
onRefresh={onRefresh}
onEndReached={onEndReached}
onEndReachedThreshold={0.3}
ListFooterComponent={loadingMore ? &lt;ActivityIndicator /&gt; : null}
/>
);
}

Когда использовать FlatList

FlatList следует использовать в следующих случаях:

  • Когда список содержит 10+ элементов.

  • Когда данные могут увеличиваться (загрузка с сервера).

  • Когда требуется виртуализация для экономии ресурсов.

  • При необходимости обновления (pull-to-refresh) или подгрузки (infinite scroll).

  • Для разделителей, заголовков, футеров, встроенных в список.

  • Если важна производительность на слабых устройствах.

Когда НЕ стоит использовать FlatList

  • Когда нужно отобразить всего 2–3 элемента — лучше обычный View + map().

  • Когда важен точный контроль над прокруткой всего содержимого (например, если нужен фиксированный ScrollView с разными блоками).

  • Когда все элементы строго фиксированы по количеству и расположению.

Альтернативы

  • ScrollView + map() — подходит для коротких списков.

  • SectionList — для отображения данных, сгруппированных по секциям (например, список писем по дате).

  • VirtualizedList — более низкоуровневая реализация, на которой основан FlatList, используется реже напрямую.

FlatList — это мощный инструмент для отображения списков в React Native, обеспечивающий высокую производительность, гибкость и функциональность при работе с любыми объемами данных.