FlatList é o principal componente do React Native para exibir listas de alto desempenho com virtualização de elementos. Ao contrário do ScrollView, o FlatList renderiza apenas os elementos visíveis da tela, economizando memória e CPU. O componente suporta rolagem horizontal e vertical, pull-to-refresh e carregamento infinito. Saiba mais sobre a arquitetura de listas em documentação da Meta.
Principais pontos
FlatList é um componente React Native que implementa uma lista virtualizada com renderização de alto desempenho para grandes conjuntos de dados. O componente é construído sobre o VirtualizedList e fornece uma API declarativa para criar listas planas de qualquer complexidade.
O FlatList foi introduzido no React Native 0.43 como substituto do obsoleto ListView. De acordo com a Meta (2026), o FlatList é usado em 85% dos aplicativos React Native que trabalham com listas. O componente suporta todos os cenários comuns: contatos, feeds de notícias, catálogos de produtos e chats.
Antes do FlatList, os desenvolvedores usavam o ListView, que exigia configuração manual de reutilização de células. O FlatList automatizou esse processo implementando renderização por janelas semelhante ao RecyclerView no Android (2014) e UICollectionView no iOS (2012). Em projetos modernos, o FlatList é o padrão de facto para qualquer lista.
A virtualização do FlatList é um mecanismo onde o componente renderiza apenas os elementos que estão dentro da área visível da tela, mais um pequeno buffer de cada lado. Os elementos restantes não são criados no DOM, economizando memória e acelerando a renderização.
Ao rolar, o FlatList reutiliza as células View já criadas, substituindo seus dados. Isso evita criar milhares de Views para uma lista de 10.000 elementos. O tamanho padrão do buffer é de 10 elementos acima e abaixo da área visível, mas é configurável através de windowSize.
| Parâmetro | Padrão | Descrição |
|---|---|---|
| windowSize | 21 | Número de páginas para renderizar (1 página = altura da tela) |
| initialNumToRender | 10 | Número de elementos na primeira renderização |
| maxToRenderPerBatch | 10 | Máximo de elementos renderizados por lote |
| removeClippedSubviews | false | Remover Views fora da tela da hierarquia |
A configuração ideal desses parâmetros permite equilibrar a suavidade da rolagem e o consumo de memória. Para listas com elementos grandes, recomenda-se reduzir windowSize para 5-7.
A API do FlatList inclui um conjunto de props para configurar a exibição e o comportamento da lista. As duas props obrigatórias são data (array de dados) e renderItem (função de renderização de elementos). keyExtractor melhora o desempenho fornecendo uma chave única para cada elemento.
import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
const App = () => {
const data = Array.from({ length: 100 }, (_, i) => ({
id: i.toString(),
title: `Item #${i + 1}`,
}));
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
);
};ItemSeparatorComponent adiciona um separador entre elementos, ListHeaderComponent e ListFooterComponent adicionam cabeçalho e rodapé à lista. Isso permite criar layouts complexos sem wrappers adicionais.
const styles = StyleSheet.create({
item: {
padding: 16,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
separator: {
height: 1,
backgroundColor: '#ccc',
},
});A otimização do FlatList é crítica para aplicativos com centenas e milhares de elementos. Sem a configuração adequada, a lista pode ficar lenta durante a rolagem, consumir memória excessiva e causar falhas em dispositivos de baixo desempenho.
A primeira regra é usar keyExtractor com identificadores únicos e estáveis. Usar índices como chaves leva à reutilização incorreta de células e bugs de estado. A segunda regra é envolver renderItem em useCallback e usar React.memo para o componente do elemento.
Se todos os elementos tiverem a mesma altura, getItemLayout permite que o FlatList calcule a posição de rolagem sem medir componentes. Isso proporciona um grande ganho de desempenho, especialmente ao rolar para um índice específico.
const ITEM_HEIGHT = 80;
const getItemLayout = (data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
});
<FlatList
data={data}
getItemLayout={getItemLayout}
renderItem={renderItem}
/FlatList>useMemo para dados evita renderizações desnecessárias. Se os dados vierem de uma API, transforme-os uma vez e armazene em cache. Use React.memo para o componente do elemento para evitar renderizar elementos inalterados.
FlatList horizontal é criado adicionando a prop horizontal={true}. A lista muda a direção da rolagem para o eixo X, o que é conveniente para carrosséis de produtos, galerias de imagens e menus horizontais.
No modo horizontal, é importante configurar corretamente snapToInterval e snapToAlignment para rolagem passo a passo como em carrosséis nativos. O componente lida automaticamente com o momentum e a liberação do dedo, parando no elemento mais próximo.
<FlatList
horizontal
data={images}
renderItem={renderItem}
keyExtractor={item => item.id}
showsHorizontalScrollIndicator={false}
snapToInterval={CARD_WIDTH + GAP}
snapToAlignment="start"
decelerationRate="fast"
pagingEnabled
onViewableItemsChanged={onViewableItemsChanged}
/>onViewableItemsChanged é um callback acionado quando os elementos visíveis mudam. É usado para análise, carregamento lento de imagens e ativação de vídeos apenas para cartões visíveis.
Pull-to-refresh no FlatList é implementado através das props refreshing e onRefresh, trabalhando em conjunto com um estado de carregamento. Ao puxar a lista para baixo, onRefresh é chamado, e a flag refreshing bloqueia chamadas repetidas.
Carregamento infinito é configurado através de onEndReached — um callback acionado ao se aproximar do final da lista. onEndReachedThreshold determina quantos elementos antes do final o evento é disparado. Geralmente é usada paginação baseada em cursor.
const ListWithPagination = () => {
const [data, setData] = React.useState([]);
const [page, setPage] = React.useState(1);
const [refreshing, setRefreshing] = React.useState(false);
const loadMore = React.useCallback(async () => {
const newData = await fetchPage(page);
setData(prev => [...prev, ...newData]);
setPage(p => p + 1);
}, [page]);
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
refreshing={refreshing}
onRefresh={loadMore}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
/>
);
};Importante: onEndReached pode ser chamado várias vezes. Adicione uma flag isLoading para bloquear requisições repetidas até que a anterior termine. Use ActivityIndicator no ListFooterComponent para indicar carregamento.
Perguntas frequentes
FlatList usa virtualização — renderiza apenas os elementos visíveis, economizando memória com grandes conjuntos de dados. ScrollView renderiza todos os filhos de uma vez, adequado apenas para listas pequenas de 20-30 elementos. FlatList é ideal para 100+ elementos.
O flash ocorre quando a referência ao array de dados muda. Use extraData passando a dependência, ou envolva renderItem em React.memo. Para controle total, use useMemo para estabilizar as referências de dados.
FlatList não foi projetado para ser aninhado dentro de ScrollView devido a conflitos de gestos. Soluções: use FlatList com nestedScrollEnabled (Android), SectionList para seções, ou mova a rolagem externa para FlatList através de ListHeaderComponent.
Use a Animated API dentro de renderItem com um atraso baseado no índice. Ao rolar, use onViewableItemsChanged para acionar animações. As bibliotecas react-native-reanimated e react-native-lottie simplificam a criação de animações complexas de aparecimento.
VirtualizedList é o componente base de virtualização sobre o qual FlatList e SectionList são construídos. FlatList é um wrapper do VirtualizedList com uma API simplificada para listas planas. VirtualizedList fornece controle de nível mais baixo, mas raramente é usado diretamente.
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