SectionList é um componente React Native para exibir listas seccionadas com elementos agrupados por categorias. Ao contrário do FlatList, o SectionList aceita um array de seções com cabeçalhos e dados, permitindo criar índices alfabéticos, catálogos e menus. O componente suporta sticky headers — cabeçalhos fixos durante a rolagem. Saiba mais sobre APIs de lista no guia oficial da Meta.
Principais pontos
SectionList é um componente React Native para exibir dados agrupados em seções lógicas. Cada seção tem um cabeçalho e uma lista de itens, ideal para contatos em ordem alfabética, menus por categoria, pedidos por data. O componente é construído sobre o VirtualizedList e herda todos os benefícios da virtualização.
O SectionList foi introduzido junto com o FlatList no React Native 0.43 e desde então se tornou o padrão para listas categorizadas. De acordo com a Meta (2026), 40% dos projetos React Native usam SectionList para organizar dados estruturados. Ao contrário do agrupamento manual dentro do FlatList, o SectionList fornece suporte integrado para seções.
SectionList é usado em listas de contatos com índice alfabético, onde cada letra é uma seção separada. No e-commerce, o componente agrupa produtos por categoria ou marca. Em aplicativos de notas — por data ou tags. Em telas de configurações — por seções (Geral, Segurança, Notificações).
De acordo com uma pesquisa de uso do React Native (Meta, 2026), o SectionList é mais eficaz com 5-50 seções contendo 3-20 itens cada. Com menos seções, é mais simples usar FlatList com agrupamento via ListHeaderComponent. Com mais seções, surgem problemas de desempenho devido ao grande número de cabeçalhos.
SectionList Data aceita um array de objetos Section, cada um contendo title (cabeçalho da seção) e data (array de itens). Opcionalmente, pode-se passar key e renderItem para cada seção separadamente, substituindo o renderItem comum.
const sections = [
{
title: 'React Native',
data: ['FlatList', 'SectionList', 'VirtualizedList'],
},
{
title: 'React',
data: ['Hooks', 'Context', 'Suspense'],
},
{
title: 'Android',
data: ['Activity', 'Fragment', 'ViewModel'],
},
];renderSectionHeader é uma função para renderizar o cabeçalho da seção, recebendo o objeto da seção. renderItem é a função de renderização de itens, similar ao FlatList. O componente também suporta renderSectionFooter para a parte inferior de cada seção.
<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 são um recurso chave do SectionList. Quando o usuário rola, o cabeçalho da seção atual fixa-se no topo da tela até que a seção seja completamente percorrida. Isso dá ao usuário contexto constante sobre a categoria atual.
O modo sticky está ativado por padrão. Para desativá-lo, use stickySectionHeadersEnabled={false}. No iOS, os cabeçalhos fixam-se com animação nativa; no Android, através do processamento JS. Para diretórios alfabéticos, é conveniente adicionar um painel lateral com letras para navegação rápida.
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 é um método para navegação programática a qualquer seção. Aceita sectionIndex, itemIndex e viewPosition (0 — início, 0.5 — centro, 1 — fim). Combinado com um índice alfabético lateral, é possível implementar navegação rápida como nos contatos padrão do iOS.
A otimização do SectionList segue os mesmos princípios da otimização do FlatList, com nuances adicionais relacionadas às seções. Cada cabeçalho de seção é uma View adicional que renderiza e re-renderiza durante a rolagem. Com 50+ seções, os cabeçalhos podem tornar a rolagem lenta.
Use React.memo para renderSectionHeader e renderItem para evitar re-renderizações desnecessárias. Se as seções não mudam dinamicamente, considere useMemo para o array de seções. Para listas muito grandes, combine SectionList com getItemLayout, especificando alturas fixas para cabeçalhos e itens.
| Técnica de otimização | Descrição | Efeito |
|---|---|---|
| React.memo | Memoização de componentes de cabeçalho e item | Reduz o número de re-renderizações durante a rolagem |
| getItemLayout | Altura fixa de cabeçalho + item | Elimina a medição, acelera a rolagem até o índice |
| maxToRenderPerBatch | Limitar itens por lote | Previne atrasos durante a rolagem rápida |
| windowSize | Reduzir para 5-10 em listas grandes | Reduz o número de itens renderizados simultaneamente |
A escolha entre SectionList e FlatList depende da estrutura dos dados. Se os dados são um array plano — use FlatList. Se os dados se agrupam naturalmente em categorias com cabeçalhos — use SectionList. Não use SectionList para uma única seção — FlatList lidará com isso de forma mais eficiente.
A diferença de desempenho é mínima com o mesmo número de itens. SectionList adiciona sobrecarga para renderizar cabeçalhos, mas essa sobrecarga é justificada quando os cabeçalhos têm significado semântico. Se os cabeçalhos não forem necessários — FlatList com ListHeaderComponent para simular seções será mais rápido.
Use SectionList quando: os dados são agrupados por padrão (contatos por letra), sticky headers são necessários, cabeçalhos de seção contêm elementos interativos (botões, checkboxes). Use FlatList quando: os dados são planos, o agrupamento muda dinamicamente, há mais de 50 categorias e os cabeçalhos são uniformes.
SectionList com índice alfabético é um caso de uso clássico. A implementação inclui um painel lateral com letras e scrollToLocation para saltar para uma seção. Abaixo está uma implementação completa de uma lista de contatos com navegação alfabética.
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>
);
};Importante: ao filtrar seções dinamicamente, use useMemo para estabilizar o array. Sem memoização, o SectionList recriará todas as células a cada alteração de filtro, causando perda da posição de rolagem e do estado dos componentes aninhados.
Perguntas frequentes
Sim, SectionList suporta alterações dinâmicas de seções. Quando o array de seções muda, o componente apenas re-renderiza as seções alteradas. Para operação estável, use uma key para cada seção e envolva os componentes em React.memo.
Filtre o array de seções antes de passá-lo: remova seções com data vazio. Se os dados vêm de uma API, lide com a filtragem no useMemo. Para o estado vazio de toda a lista, use ListEmptyComponent.
Sticky headers no Android estão ativados por padrão, mas podem não funcionar em conflito com nestedScrollEnabled. Certifique-se de que o SectionList não esteja aninhado dentro de um ScrollView. No Android 12+, os sticky headers funcionam através do mecanismo nativo; em versões antigas, via JS.
O SectionList não fornece uma animação de transição integrada para sticky headers. Para animação personalizada, monitore onViewableItemsChanged e anime a mudança de cabeçalho usando Animated API ou react-native-reanimated.
Sim, cada seção adiciona um cabeçalho ao DOM. Com 100+ seções, o desempenho do SectionList diminui devido ao grande número de cabeçalhos. Solução: agrupe os dados em 10-20 seções lógicas ou use FlatList com agrupamento personalizado.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também