SectionList — komponenta React Native pro zobrazení sekcionovaných seznamů s seskupováním prvků podle kategorií. Na rozdíl od FlatList, SectionList přijímá pole sekcí s nadpisy a daty, což umožňuje vytvářet abecední rejstříky, katalogy a menu. Komponenta podporuje sticky headers — přichycené nadpisy při scrollování. Více o API seznamů se dočtete v oficiálním průvodci Meta.
Hlavní
SectionList — komponenta React Native pro zobrazení dat seskupených do logických sekcí. Každá sekce má nadpis a seznam prvků, což je ideální pro kontakty podle abecedy, menu podle kategorií, objednávky podle dat. Komponenta je postavena na VirtualizedList a dědí všechny výhody virtualizace.
SectionList se objevil spolu s FlatList v React Native 0.43 a od té doby je standardem pro kategorizované seznamy. Podle údajů Meta (2026) používá 40% projektů na React Native SectionList pro organizaci strukturovaných dat. Na rozdíl od ručního seskupování uvnitř FlatList poskytuje SectionList vestavěnou podporu pro sekce.
SectionList se používá v kontaktních seznamech s abecedním rejstříkem, kde každé písmeno je samostatná sekce. V e-commerce komponenta seskupuje produkty podle kategorií nebo značek. V aplikacích pro poznámky — podle dat nebo štítků. V nastavení — podle sekcí (Základní, Zabezpečení, Oznámení).
Podle výzkumu používání React Native (Meta, 2026) je SectionList nejefektivnější při 5–50 sekcích s 3–20 prvky v každé. Při menším počtu sekcí je jednodušší použít FlatList s seskupováním přes ListHeaderComponent. Při větším — vznikají problémy s výkonem kvůli velkému počtu nadpisů.
SectionList Data přijímá pole objektů Section, z nichž každý obsahuje title (nadpis sekce) a data (pole prvků). Dále lze pro každou sekci zvlášť předávat key a renderItem, přepisující obecný renderItem.
const sections = [
{
title: 'React Native',
data: ['FlatList', 'SectionList', 'VirtualizedList'],
},
{
title: 'React',
data: ['Hooks', 'Context', 'Suspense'],
},
{
title: 'Android',
data: ['Activity', 'Fragment', 'ViewModel'],
},
];renderSectionHeader — funkce vykreslování nadpisu sekce, která přijímá objekt sekce. renderItem — funkce vykreslování prvku, analogická FlatList. Komponenta také podporuje renderSectionFooter pro spodní část každé sekce.
<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 — klíčová vlastnost SectionList. Když uživatel scrolluje, nadpis aktuální sekce přilne k hornímu okraji obrazovky, dokud není sekce zcela proscrollována. To poskytuje uživateli stálý kontext o aktuální kategorii.
Režim sticky je ve výchozím nastavení zapnutý. Pro vypnutí použijte stickySectionHeadersEnabled={false}. Na iOS nadpisy přilnou s nativní animací, na Androidu — přes JS. Pro abecední rejstříky je vhodné přidat boční panel s písmeny pro rychlou navigaci.
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 — metoda pro programovou navigaci k libovolné sekci. Přijímá sectionIndex, itemIndex a viewPosition (0 — začátek, 0.5 — střed, 1 — konec). Kombinací s bočním abecedním rejstříkem lze implementovat rychlou navigaci jako ve standardních kontaktech iOS.
Optimalizace SectionList se řídí stejnými principy jako optimalizace FlatList, s dodatečnými nuancemi souvisejícími se sekcemi. Každý nadpis sekce je dodatečný View, který se vykresluje a překresluje při scrollování. Při 50+ sekcích mohou nadpisy zpomalit scrollování.
Používejte React.memo pro renderSectionHeader a renderItem, abyste předešli zbytečnému překreslování. Pokud se sekce nemění dynamicky, zvažte useMemo pro pole sections. Pro velmi velké seznamy kombinujte SectionList s getItemLayout, zadávajíc pevnou výšku nadpisů a prvků.
| Technika optimalizace | Popis | Efekt |
|---|---|---|
| React.memo | Memoizace komponent nadpisů a prvků | Snižuje počet překreslení při scrollování |
| getItemLayout | Pevná výška nadpisu + prvku | Odstraňuje měření, zrychluje scrollování na index |
| maxToRenderPerBatch | Omezení prvků v dávce | Zabraňuje zpožděním při rychlém scrollování |
| windowSize | Snižení na 5–10 pro velké seznamy | Snižuje počet současně vykreslených prvků |
Výběr mezi SectionList a FlatList závisí na struktuře dat. Pokud data představují ploché pole — použijte FlatList. Pokud se data přirozeně seskupují do kategorií s nadpisy — SectionList. Nepoužívejte SectionList pro jednu sekci — FlatList bude efektivnější.
Rozdíl ve výkonu je minimální při stejném počtu prvků. SectionList přidává režii na vykreslování nadpisů, ale tato režie je oprávněná, když nadpisy nesou význam. Pokud nadpisy nejsou potřeba — FlatList s ListHeaderComponent pro simulaci sekcí bude rychlejší.
Používejte SectionList, když: data jsou standardně seskupena (kontakty podle písmen), jsou potřeba sticky headers, nadpisy sekcí obsahují interaktivní prvky (tlačítka, zaškrtávací políčka). Používejte FlatList, když: data jsou plochá, seskupení se dynamicky mění, kategorií je více než 50 a nadpisy jsou jednotné.
SectionList s abecedním rejstříkem — klasický příklad použití. Implementace zahrnuje boční panel s písmeny a scrollToLocation pro skok k sekci. Níže je úplná implementace kontaktního seznamu s abecední navigací.
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>
);
};Důležité: při dynamickém filtrování sekcí používejte useMemo pro stabilizaci pole. Bez memoizace bude SectionList při každé změně filtru znovu vytvářet všechny buňky, což vede ke ztrátě scrollování a stavu vnořených komponent.
Často kladené otázky
Ano, SectionList podporuje dynamické změny sekcí. Při změně pole sections komponent překreslí pouze změněné sekce. Pro stabilní provoz používejte key pro každou sekci a obalujte komponenty do React.memo.
Filtrujte pole sections před předáním: odstraňte sekce s prázdným data. Pokud data přicházejí z API, provádějte filtrování v useMemo. Pro prázdný stav celého seznamu použijte ListEmptyComponent.
Sticky headers na Androidu jsou ve výchozím nastavení zapnuté, ale mohou nefungovat při konfliktu s nestedScrollEnabled. Ujistěte se, že SectionList není vnořen do ScrollView. Na Android 12+ sticky headers fungují přes nativní mechanismus, na starších verzích — přes JS.
SectionList neposkytuje vestavěnou animaci změny sticky header. Pro vlastní animaci sledujte onViewableItemsChanged a animujte změnu nadpisu přes Animated API nebo react-native-reanimated.
Ano, každá sekce přidává nadpis do DOM. Při 100+ sekcích výkon SectionList klesá kvůli velkému počtu nadpisů. Řešení: seskupte data do 10–20 logických sekcí nebo použijte FlatList s vlastním seskupováním.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také