SectionList — компонент React Native для отображения секционированных списков с группировкой элементов по категориям. В отличие от FlatList, SectionList принимает массив секций с заголовками и данными, что позволяет создавать алфавитные указатели, каталоги и меню. Компонент поддерживает sticky headers — закреплённые заголовки при скролле. Подробнее об API списков читайте в официальном руководстве Meta.
Главное
SectionList — компонент React Native для отображения данных, сгруппированных в логические секции. Каждая секция имеет заголовок и список элементов, что идеально для контактов по алфавиту, меню по категориям, заказов по датам. Компонент построен на VirtualizedList и наследует все преимущества виртуализации.
SectionList появился вместе с FlatList в React Native 0.43 и с тех пор является стандартом для категоризированных списков. По данным Meta (2026), 40% проектов на React Native используют SectionList для организации структурированных данных. В отличие от ручной группировки внутри FlatList, SectionList предоставляет встроенную поддержку секций.
SectionList применяется в контакт-листах с алфавитным указателем, где каждая буква — отдельная секция. В e-commerce компонент группирует товары по категориям или брендам. В приложениях для заметок — по датам или тегам. В настройках — по разделам (Основные, Безопасность, Уведомления).
По данным исследования использования React Native (Meta, 2026), SectionList наиболее эффективен при 5-50 секциях с 3-20 элементами в каждой. При меньшем количестве секций проще использовать FlatList с группировкой через ListHeaderComponent. При большем — возникают проблемы с производительностью из-за большого числа заголовков.
SectionList Data принимает массив объектов Section, каждый из которых содержит title (заголовок секции) и data (массив элементов). Дополнительно можно передавать key и renderItem для каждой секции отдельно, переопределяя общий renderItem.
const sections = [
{
title: 'React Native',
data: ['FlatList', 'SectionList', 'VirtualizedList'],
},
{
title: 'React',
data: ['Hooks', 'Context', 'Suspense'],
},
{
title: 'Android',
data: ['Activity', 'Fragment', 'ViewModel'],
},
];renderSectionHeader — функция рендеринга заголовка секции, получающая объект секции. renderItem — функция рендеринга элемента, аналогичная FlatList. Компонент также поддерживает renderSectionFooter для нижней части каждой секции.
<SectionList
sections={sections}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item}</Text>
</View>
)}
renderSectionHeader={({ section }) => (
<View style={styles.sectionHeader}>
<Text style={styles.sectionTitle}>{section.title}</Text>
</View>
)}
/>Sticky headers — ключевая особенность SectionList. Когда пользователь скроллит, заголовок текущей секции прилипает к верхнему краю экрана, пока секция полностью не проскроллится. Это даёт пользователю постоянный контекст о текущей категории.
Режим sticky включён по умолчанию. Для отключения используйте stickySectionHeadersEnabled={false}. На iOS заголовки прилипают с нативной анимацией, на Android — через JS-обработку. Для алфавитных справочников удобно добавить боковую панель с буквами для быстрой навигации.
const ContactsList = () => {
const sectionListRef = React.useRef(null);
const scrollToSection = (index) => {
sectionListRef.current?.scrollToLocation({
sectionIndex: index,
itemIndex: 0,
viewPosition: 0,
});
};
return (
<View>
<SectionList
ref={sectionListRef}
sections={sections}
keyExtractor={(item) => item.id}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
onViewableItemsChanged={onViewableItemsChanged}
/>
</View>
);
};scrollToLocation — метод для программной навигации к любой секции. Принимает sectionIndex, itemIndex и viewPosition (0 — начало, 0.5 — центр, 1 — конец). Комбинируя с боковым алфавитным индексом, можно реализовать быструю навигацию как в стандартных контактах iOS.
Оптимизация SectionList следует тем же принципам, что и оптимизация FlatList, с дополнительными нюансами, связанными с секциями. Каждый заголовок секции — дополнительный View, который рендерится и перерендеривается при скролле. При 50+ секциях заголовки могут замедлить скролл.
Используйте React.memo для renderSectionHeader и renderItem, чтобы избежать лишних перерендеров. Если секции не меняются динамически, рассмотрите useMemo для массива sections. Для очень больших списков комбинируйте SectionList с getItemLayout, указывая фиксированную высоту заголовков и элементов.
| Приём оптимизации | Описание | Эффект |
|---|---|---|
| React.memo | Мемоизация компонентов заголовков и элементов | Снижает количество перерендеров при скролле |
| getItemLayout | Фиксированная высота заголовка + элемента | Убирает измерение, ускоряет скролл до index |
| maxToRenderPerBatch | Ограничение элементов в батче | Предотвращает задержки при быстром скролле |
| windowSize | Уменьшение до 5-10 для больших списков | Снижает количество одновременно зарендеренных элементов |
Выбор между SectionList и FlatList зависит от структуры данных. Если данные представляют собой плоский массив — используйте FlatList. Если данные естественным образом группируются в категории с заголовками — SectionList. Не используйте SectionList для одной секции — FlatList справится эффективнее.
Разница в производительности минимальна при одинаковом количестве элементов. SectionList добавляет overhead на рендеринг заголовков, но этот overhead оправдан, когда заголовки несут смысловую нагрузку. Если заголовки не нужны — FlatList с ListHeaderComponent для имитации секций будет быстрее.
Используйте SectionList, когда: данные сгруппированы по умолчанию (контакты по буквам), нужны sticky headers, заголовки секций содержат интерактивные элементы (кнопки, чекбоксы). Используйте FlatList, когда: данные плоские, группировка меняется динамически, категорий больше 50 и заголовки однотипны.
SectionList с алфавитным указателем — классический пример использования. Реализация включает боковую панель с буквами и scrollToLocation для прыжка к секции. Ниже — полная реализация контакт-листа с алфавитной навигацией.
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
const AlphabetContacts = () => {
const ref = React.useRef(null);
const sections = React.useMemo(() =>
ALPHABET.map(letter => ({
title: letter,
data: contacts.filter(c => c.name.startsWith(letter)),
})).filter(s => s.data.length > 0),
[]);
return (
<View style={styles.container}>
<SectionList
ref={ref}
sections={sections}
keyExtractor={item => item.id}
renderItem={renderContact}
renderSectionHeader={renderHeader}
getItemLayout={getItemLayout}
/>
<View style={styles.sidebar}>
{ALPHABET.map(letter => (
<Text
key={letter}
onPress={() => scrollToSection(letter)}
>{letter}</Text>
))}
</View>
</View>
);
};Важно: при динамической фильтрации секций используйте useMemo для стабилизации массива. Без мемоизации SectionList будет пересоздавать все ячейки при каждом изменении фильтра, что приведёт к потери скролла и состояния вложенных компонентов.
Часто задаваемые вопросы
Да, SectionList поддерживает динамическое изменение секций. При изменении массива sections компонент перерендерит только изменившиеся секции. Для стабильной работы используйте key для каждой секции и оборачивайте компоненты в React.memo.
Фильтруйте массив sections перед передачей: отфильтруйте секции с пустым data. Если данные приходят из API, обрабатывайте фильтрацию в useMemo. Для пустого состояния всего списка используйте ListEmptyComponent.
Sticky headers на Android включены по умолчанию, но могут не работать при конфликте с nestedScrollEnabled. Убедитесь, что SectionList не вложен в ScrollView. На Android 12+ sticky headers работают через нативный механизм, на старых версиях — через JS.
SectionList не предоставляет встроенной анимации смены sticky header. Для кастомной анимации отслеживайте onViewableItemsChanged и анимируйте смену заголовка через Animated API или react-native-reanimated.
Да, каждая секция добавляет заголовок в DOM. При 100+ секциях производительность SectionList падает из-за большого числа заголовков. Решение: сгруппируйте данные в 10-20 логических секций или используйте FlatList с кастомной группировкой.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также