Master React Native Vertical and Horizontal Scrolling Lists

Last update: 2025-04-24
Type
Quick Win's logo Quick Win
Membership
🆓
Tech
TypeScript TypeScript
TypeScript
Share:

Scrolling lists are a fundamental part of most mobile applications. React Native provides several components for implementing both vertical and horizontal scrolling. In this guide, you’ll learn how to use these components effectively with practical examples.

ScrollView vs FlatList

React Native offers two main components for creating scrollable content:

  1. ScrollView: Best for a small number of items that are all rendered at once
  2. FlatList: Optimized for long lists with lazy loading and better performance

Let’s explore both approaches.

Basic ScrollView Implementation

ScrollView is perfect for simple scrolling needs:

import React from 'react';
import { View, ScrollView, Text, StyleSheet } from 'react-native';

const ScrollViewExample = () => {
	return (
		<View style={styles.container}>
			<ScrollView style={styles.scrollView}>
				{[1, 2, 3, 4, 5].map((item) => (
					<View key={item} style={styles.item}>
						<Text style={styles.text}>Item {item}</Text>
					</View>
				))}
			</ScrollView>
		</View>
	);
};

const styles = StyleSheet.create({
	container: {
		flex: 1
	},
	scrollView: {
		marginHorizontal: 20
	},
	item: {
		backgroundColor: '#f9c2ff',
		padding: 20,
		marginVertical: 8,
		borderRadius: 8
	},
	text: {
		fontSize: 16
	}
});

export default ScrollViewExample;

This example demonstrates:

  • Basic vertical scrolling with ScrollView
  • Simple styling for container and items
  • Manual rendering of list items

Horizontal ScrollView

For horizontal scrolling, just add the horizontal prop:

import React from 'react';
import { View, ScrollView, Text, StyleSheet, Dimensions } from 'react-native';

const HorizontalScrollViewExample = () => {
	return (
		<View style={styles.container}>
			<ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.scrollView}>
				{[1, 2, 3, 4, 5].map((item) => (
					<View key={item} style={styles.card}>
						<Text style={styles.cardText}>Card {item}</Text>
					</View>
				))}
			</ScrollView>
		</View>
	);
};

const { width } = Dimensions.get('window');

const styles = StyleSheet.create({
	container: {
		flex: 1
	},
	scrollView: {
		paddingVertical: 20
	},
	card: {
		width: width * 0.8,
		height: 200,
		backgroundColor: '#4a90e2',
		marginHorizontal: 10,
		borderRadius: 12,
		justifyContent: 'center',
		alignItems: 'center'
	},
	cardText: {
		color: 'white',
		fontSize: 24,
		fontWeight: 'bold'
	}
});

export default HorizontalScrollViewExample;

Key features demonstrated:

  • Horizontal scrolling enabled with horizontal prop
  • Card-style layout with dynamic width
  • Hidden scroll indicator for cleaner UI
  • Proper spacing between cards

FlatList for Better Performance

For longer lists, FlatList is the recommended choice:

import React from 'react';
import { View, FlatList, Text, StyleSheet } from 'react-native';

interface Item {
	id: string;
	title: string;
}

const DATA: Item[] = Array.from({ length: 50 }, (_, i) => ({
	id: i.toString(),
	title: `Item ${i + 1}`
}));

const FlatListExample = () => {
	const renderItem = ({ item }: { item: Item }) => (
		<View style={styles.item}>
			<Text style={styles.title}>{item.title}</Text>
		</View>
	);

	return (
		<View style={styles.container}>
			<FlatList
				data={DATA}
				renderItem={renderItem}
				keyExtractor={(item) => item.id}
				ItemSeparatorComponent={() => <View style={styles.separator} />}
				ListHeaderComponent={() => <Text style={styles.header}>My List</Text>}
				ListFooterComponent={() => <Text style={styles.footer}>End of List</Text>}
				onEndReached={() => {
					console.log('Reached end of list');
					// Load more data here
				}}
				onEndReachedThreshold={0.5}
			/>
		</View>
	);
};

const styles = StyleSheet.create({
	container: {
		flex: 1
	},
	item: {
		backgroundColor: '#ffffff',
		padding: 20,
		borderRadius: 8,
		shadowColor: '#000',
		shadowOffset: {
			width: 0,
			height: 2
		},
		shadowOpacity: 0.25,
		shadowRadius: 3.84,
		elevation: 5
	},
	title: {
		fontSize: 16
	},
	separator: {
		height: 16
	},
	header: {
		fontSize: 24,
		fontWeight: 'bold',
		padding: 16
	},
	footer: {
		padding: 16,
		textAlign: 'center',
		color: '#666'
	}
});

export default FlatListExample;

This FlatList example showcases:

  • Type-safe data with TypeScript interface
  • Custom item rendering
  • Separator component between items
  • Header and footer components
  • Infinite scrolling setup with onEndReached
  • Elegant styling with shadows

Horizontal FlatList with Cards

Here’s how to create a horizontal scrolling list with FlatList:

import React from 'react';
import { View, FlatList, Text, StyleSheet, Dimensions, Image } from 'react-native';

interface Card {
	id: string;
	title: string;
	image: string;
}

const CARDS: Card[] = [
	{
		id: '1',
		title: 'Nature',
		image: 'https://picsum.photos/300/200?random=1'
	},
	{
		id: '2',
		title: 'City',
		image: 'https://picsum.photos/300/200?random=2'
	},
	{
		id: '3',
		title: 'Technology',
		image: 'https://picsum.photos/300/200?random=3'
	}
	// Add more cards as needed
];

const HorizontalFlatListExample = () => {
	const renderCard = ({ item }: { item: Card }) => (
		<View style={styles.card}>
			<Image source={{ uri: item.image }} style={styles.cardImage} />
			<Text style={styles.cardTitle}>{item.title}</Text>
		</View>
	);

	return (
		<View style={styles.container}>
			<FlatList
				data={CARDS}
				renderItem={renderCard}
				keyExtractor={(item) => item.id}
				horizontal
				showsHorizontalScrollIndicator={false}
				snapToAlignment="center"
				snapToInterval={width * 0.8 + 20}
				decelerationRate="fast"
				contentContainerStyle={styles.contentContainer}
			/>
		</View>
	);
};

const { width } = Dimensions.get('window');

const styles = StyleSheet.create({
	container: {
		flex: 1
	},
	contentContainer: {
		paddingHorizontal: 10,
		paddingVertical: 20
	},
	card: {
		width: width * 0.8,
		marginHorizontal: 10,
		borderRadius: 12,
		backgroundColor: 'white',
		shadowColor: '#000',
		shadowOffset: {
			width: 0,
			height: 2
		},
		shadowOpacity: 0.25,
		shadowRadius: 3.84,
		elevation: 5,
		overflow: 'hidden'
	},
	cardImage: {
		width: '100%',
		height: 200
	},
	cardTitle: {
		fontSize: 18,
		fontWeight: 'bold',
		padding: 16
	}
});

export default HorizontalFlatListExample;

This example demonstrates:

  • Horizontal scrolling with FlatList
  • Snap-to-item behavior
  • Card layout with images
  • Smooth scrolling optimization
  • Proper touch feedback

Performance Optimization Tips

  1. Use FlatList for Long Lists

    • Implements virtualization
    • Only renders visible items
    • Better memory management
  2. Optimize Rendering

    const renderItem = React.useCallback(({ item }) => <Item item={item} />, []);
  3. Implement getItemLayout

    const getItemLayout = (data, index) => ({
    	length: ITEM_HEIGHT,
    	offset: ITEM_HEIGHT * index,
    	index
    });
  4. Adjust Window Size

    <FlatList windowSize={5} maxToRenderPerBatch={5} initialNumToRender={10} />

Pull to Refresh

Add refresh functionality to your lists:

const [refreshing, setRefreshing] = React.useState(false);

const onRefresh = React.useCallback(() => {
	setRefreshing(true);
	// Fetch new data here
	setTimeout(() => {
		setRefreshing(false);
	}, 2000);
}, []);

<FlatList
	refreshing={refreshing}
	onRefresh={onRefresh}
	// ... other props
/>;

Best Practices

  1. Choose the Right Component

    • Use ScrollView for small lists (less than 20 items)
    • Use FlatList for longer lists
    • Consider SectionList for grouped data
  2. Performance

    • Implement proper key extraction
    • Optimize render methods
    • Use pagination for large datasets
  3. User Experience

    • Add loading indicators
    • Implement pull-to-refresh
    • Show empty state components
    • Handle errors gracefully
  4. Styling

    • Maintain consistent spacing
    • Consider platform differences
    • Implement proper touch feedback
    • Use shadows and borders wisely

Common Use Cases

  • Social media feeds
  • Product catalogs
  • Image galleries
  • Chat messages
  • Settings menus

Summary

React Native’s scrolling components provide powerful tools for creating smooth, performant lists. By choosing the right component and following best practices, you can create beautiful scrolling experiences in your apps.

Key takeaways:

  • Use ScrollView for simple, short lists
  • Choose FlatList for better performance with long lists
  • Implement proper optimization techniques
  • Follow platform-specific design guidelines
  • Consider user experience in your implementation

Now you’re ready to implement beautiful scrolling lists in your React Native apps! 🚀

Zero to Hero React Native Mission
Simon Grimm