O componente ScrollView no React Native é um contêiner que permite rolar o conteúdo que excede o tamanho da tela. Ao contrário do FlatList, o ScrollView renderiza todo o conteúdo de uma vez, sendo ideal para pequenas quantidades de dados, formulários e telas com altura conhecida. De acordo com a React Native Docs, 2024, o ScrollView suporta rolagem vertical e horizontal, o evento onScroll, controle programático de posição e gestos de zoom. O componente é renderizado no UIScrollView nativo no iOS e no ScrollView no Android.
Principais pontos
ScrollView é um componente React Native que envolve seu conteúdo em um contêiner rolável. Se o conteúdo exceder os limites da tela, o usuário pode rolar vertical ou horizontalmente. O ScrollView renderiza todos os elementos filhos na montagem, independentemente de estarem visíveis na tela ou não.
Ao contrário do FlatList, que renderiza apenas os elementos visíveis (renderização preguiçosa), o ScrollView cria todas as visualizações nativas imediatamente. Isso torna o ScrollView conveniente para formulários, páginas de configuração, cartões de produto em uma única tela — em qualquer lugar onde o número de elementos filhos seja pequeno (até 20-30) ou sua quantidade exata seja desconhecida antecipadamente.
De acordo com o React Native Using ScrollView, 2024, o ScrollView suporta rolagem aninhada (por exemplo, ScrollView dentro de ScrollView), efeito de ressalto ao atingir a borda, indicadores de rolagem, posicionamento snap e manipulação de gestos. No iOS, o ScrollView adiciona automaticamente o padding do SafeArea através do contentInsetAdjustmentBehavior.
ScrollView fornece um conjunto rico de propriedades para controlar o comportamento da rolagem, aparência e interatividade. Vamos ver os grupos principais: controle de rolagem, configurações visuais, eventos e recursos específicos da plataforma.
horizontal — alterna a direção da rolagem de vertical (padrão) para horizontal. scrollEnabled — desabilita a rolagem quando necessário. showsVerticalScrollIndicator e showsHorizontalScrollIndicator controlam a exibição dos indicadores de rolagem. bounces (iOS) ativa/desativa o efeito de ressalto ao atingir a borda do conteúdo.
O evento principal é onScroll, que é disparado a cada rolagem e passa um objeto com nativeEvent contendo contentOffset (posição atual), contentSize (tamanho do conteúdo), layoutMeasurement (tamanho da área visível). onMomentumScrollEnd é disparado após a conclusão da rolagem inercial. onScrollEndDrag — quando o usuário levanta o dedo da tela. Esses eventos são usados para implementar rolagem infinita, efeitos de parallax e carregamento preguiçoso.
O ScrollView fornece métodos para controle programático via ref: scrollTo({x, y, animated}) rola para as coordenadas especificadas, scrollToEnd({animated}) — rola para o final do conteúdo, flashScrollIndicators() — mostra temporariamente os indicadores de rolagem.
const scrollRef = useRef(null);
// Rolar para o topo
scrollRef.current.scrollTo({ x: 0, y: 0, animated: true });
// Rolar para o final
scrollRef.current.scrollToEnd({ animated: true });
O controle programático da rolagem é frequentemente usado em chats (rolagem automática para a última mensagem), formulários (rolagem para um campo com erro) e carrosséis (deslizamento programático).
Escolher entre ScrollView e FlatList é uma das decisões arquitetônicas chave no React Native. Ambos os componentes fornecem rolagem, mas usam estratégias de renderização fundamentalmente diferentes. O ScrollView renderiza tudo de uma vez, o FlatList — apenas os elementos visíveis.
| Característica | ScrollView | FlatList |
|---|---|---|
| Renderização | Todos os elementos de uma vez | Apenas visíveis + buffer |
| Desempenho | Degrada com 30+ elementos | Estável em qualquer quantidade |
| Conteúdo | Qualquer componente (formulários, cartões) | Elementos uniformes de array |
| Tamanho dos dados | Pequeno e médio (até 30 elementos) | Grande e ilimitado |
| Rolagem horizontal | Sim (prop horizontal) | Sim (horizontal) |
| Seções | Não (renderiza como está) | SectionList para seções |
Regra de seleção: ScrollView — para telas onde o número de elementos filhos é conhecido e não excede 20-30 (perfil de usuário, formulário de configuração, página de produto). FlatList — para listas com potencialmente muitos elementos (feed de notícias, catálogo de produtos, mensagens de chat). Se o conteúdo for heterogêneo (cabeçalho, formulário, cartão, rodapé) — o ScrollView é preferível, pois o FlatList espera elementos uniformes.
ScrollView suporta rolagem horizontal através da prop horizontal, tornando-o ideal para carrosséis, galerias de imagens, abas e listas horizontais. Quando combinado com a prop pagingEnabled (iOS) ou snapToInterval, o ScrollView se torna um componente para navegação por páginas.
A propriedade horizontal altera a direção da rolagem. pagingEnabled (iOS) ativa a rolagem por páginas, onde a rolagem para apenas nos limites dos elementos. snapToInterval define o passo de snap em pixels para ambas as plataformas.
const ImageCarousel = ({ images }) => (
<ScrollView
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
onMomentumScrollEnd={handlePageChange}
>
{images.map((img, index) => (
<Image
key={index}
source={{ uri: img }}
style={{ width: SCREEN_WIDTH, height: 250 }}
/>
))}
</ScrollView>
);
Neste carrossel, pagingEnabled ajusta automaticamente a rolagem aos limites de cada imagem. onMomentumScrollEnd permite atualizar o indicador da página atual. Esse carrossel funciona nativamente e suporta rolagem inercial.
Para passos de snap não padrão, use snapToInterval (tamanho do passo em pixels) e snapToAlignment (start, center, end). Com snapToOffsets você pode especificar um array de posições específicas para snap. Isso é útil para listas horizontais com cartões de tamanhos diferentes.
Vamos ver dois cenários típicos: uma tela com formulário (rolagem vertical) e uma lista horizontal de categorias. Ambos usam ScrollView com diferentes props para comportamento ideal.
Uma página de edição de perfil contém elementos heterogêneos: avatar, vários campos de entrada, interruptores e um botão de salvar. O ScrollView permite rolar a página inteira como um todo, em vez de cada bloco separadamente.
const ProfileScreen = () => (
<ScrollView
contentContainerStyle={styles.container}
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={false}
>
<AvatarPicker />
<TextInput placeholder="Name" />
<TextInput placeholder="Email" />
<TextInput placeholder="About me" multiline />
<SwitchRow label="Notifications" />
<Button title="Save" />
</ScrollView>
);
A prop keyboardShouldPersistTaps: 'handled' permite rolar e interagir com o formulário quando o teclado está aberto. contentContainerStyle aplica padding a todo o conteúdo. Este padrão é usado em todas as telas com formulários no React Native.
Para navegar por categorias (chats, filtros, abas), um ScrollView horizontal com chips é usado. Este componente é comumente encontrado em aplicativos de marketplace e redes sociais.
const CategoryChips = ({ categories, selected, onSelect }) => (
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.chipContainer}
>
{categories.map((cat) => (
<Chip
key={cat.id}
label={cat.name}
isSelected={selected === cat.id}
onPress={() => onSelect(cat.id)}
/>
))}
</ScrollView>
);
Um ScrollView horizontal com o indicador desativado é o padrão para tiras de categorias. Cada chip é um componente separado com estado de seleção. A prop showsHorizontalScrollIndicator: false remove a barra de rolagem, o que corresponde às expectativas dos usuários de aplicativos móveis.
Perguntas frequentes
O ScrollView é adequado para pequenas quantidades de dados (até 20-30 elementos) e conteúdo heterogêneo (formulários, perfis, telas de configuração). Escolha FlatList para listas longas uniformes — feed de notícias, catálogo de produtos, mensagens.
Use o evento onScroll com onScrollEndDrag ou onMomentumScrollEnd. A posição vertical atual está em nativeEvent.contentOffset.y. Para desempenho, use ScrollEventThrottle (iOS) para ajustar a frequência de chamada do onScroll.
O ScrollView renderiza todos os elementos na montagem, criando visualizações nativas para cada um. Com 50+ elementos na tela, a carga de memória e a thread JS aumentam, causando queda de quadros. Para esses casos, use FlatList com renderização preguiçosa.
Defina bounces={false}. Esta prop funciona apenas no iOS e desativa o efeito elástico ao atingir a borda do ScrollView. No Android, não há efeito de ressalto por padrão, então a prop é ignorada.
O ScrollView não suporta rolagem infinita nativamente. No entanto, você pode combinar onScroll com verificação de proximidade à borda inferior (contentOffset.y + altura da tela >= contentSize.height) e adicionar elementos ao estado. Para volumes grandes, use FlatList com onEndReached.
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