Что такое 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 }) => (
<View>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
);
}
Как работает renderItem
Проп renderItem принимает функцию, которая получает объект:
{
item, // текущий элемент массива
index, // индекс элемента
separators // методы управления разделителями (реже используется)
}
Пример с индексом:
renderItem={({ item, index }) => (
<Text>{index + 1}. {item.title}</Text>
)}
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={<Text>Заголовок</Text>}
ListFooterComponent={<Text>Конец списка</Text>}
ItemSeparatorComponent={() => <View style={{ height: 1, backgroundColor: '#ccc' }} />}
/>
Горизонтальный список
Для отображения элементов в строку:
<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 }) => <Text>{item.name}</Text>}
keyExtractor={(item) => item.id.toString()}
refreshing={refreshing}
onRefresh={onRefresh}
onEndReached={onEndReached}
onEndReachedThreshold={0.3}
ListFooterComponent={loadingMore ? <ActivityIndicator /> : null}
/>
);
}
Когда использовать FlatList
FlatList следует использовать в следующих случаях:
-
Когда список содержит 10+ элементов.
-
Когда данные могут увеличиваться (загрузка с сервера).
-
Когда требуется виртуализация для экономии ресурсов.
-
При необходимости обновления (pull-to-refresh) или подгрузки (infinite scroll).
-
Для разделителей, заголовков, футеров, встроенных в список.
-
Если важна производительность на слабых устройствах.
Когда НЕ стоит использовать FlatList
-
Когда нужно отобразить всего 2–3 элемента — лучше обычный View + map().
-
Когда важен точный контроль над прокруткой всего содержимого (например, если нужен фиксированный ScrollView с разными блоками).
-
Когда все элементы строго фиксированы по количеству и расположению.
Альтернативы
-
ScrollView + map() — подходит для коротких списков.
-
SectionList — для отображения данных, сгруппированных по секциям (например, список писем по дате).
-
VirtualizedList — более низкоуровневая реализация, на которой основан FlatList, используется реже напрямую.
FlatList — это мощный инструмент для отображения списков в React Native, обеспечивающий высокую производительность, гибкость и функциональность при работе с любыми объемами данных.