FlatList & SectionList
Master FlatList and SectionList components for efficient rendering of large lists in React Native applications
60 min•By Priygop Team•Last updated: Feb 2026
FlatList Component
FlatList is a performant interface for rendering basic, flat lists with support for most common use cases like horizontal mode, header/footer, pull-to-refresh, and more.
FlatList Properties
- data - Array of items to render
- renderItem - Function to render each item
- keyExtractor - Function to extract unique keys
- getItemLayout - Optimize performance with known item dimensions
- onEndReached - Callback when reaching the end
- refreshing - Pull-to-refresh state
- onRefresh - Pull-to-refresh callback
SectionList Component
SectionList is a performant interface for rendering sectioned lists with support for sticky section headers, section separators, and more.
Performance Optimization
Use getItemLayout, keyExtractor, and removeClippedSubviews for optimal performance with large datasets.
Advanced FlatList Example
Example
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, TouchableOpacity, StyleSheet, RefreshControl, ActivityIndicator } from 'react-native';
const AdvancedFlatList = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [refreshing, setRefreshing] = useState(false);
const [page, setPage] = useState(1);
const loadData = async (pageNum = 1, isRefresh = false) => {
if (isRefresh) {
setRefreshing(true);
} else {
setLoading(true);
}
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 1000));
const newData = Array.from({ length: 20 }, (_, i) => ({
id: (pageNum - 1) * 20 + i + 1,
title: `Item ${(pageNum - 1) * 20 + i + 1}`,
subtitle: `This is subtitle for item ${(pageNum - 1) * 20 + i + 1}`,
timestamp: new Date().toISOString(),
}));
if (isRefresh) {
setData(newData);
setPage(1);
} else {
setData(prev => [...prev, ...newData]);
setPage(pageNum);
}
} catch (error) {
console.error('Error loading data:', error);
} finally {
setLoading(false);
setRefreshing(false);
}
};
useEffect(() => {
loadData();
}, []);
const onRefresh = () => {
loadData(1, true);
};
const onEndReached = () => {
if (!loading) {
loadData(page + 1);
}
};
const renderItem = ({ item, index }) => (
<TouchableOpacity style={styles.item}>
<Text style={styles.itemTitle}>{item.title}</Text>
<Text style={styles.itemSubtitle}>{item.subtitle}</Text>
<Text style={styles.itemTimestamp}>
{new Date(item.timestamp).toLocaleString()}
</Text>
</TouchableOpacity>
);
const renderHeader = () => (
<View style={styles.header}>
<Text style={styles.headerTitle}>Advanced FlatList</Text>
<Text style={styles.headerSubtitle}>Pull to refresh, infinite scroll</Text>
</View>
);
const renderFooter = () => {
if (!loading) return null;
return (
<View style={styles.footer}>
<ActivityIndicator size="small" color="#2196F3" />
<Text style={styles.footerText}>Loading more...</Text>
</View>
);
};
const renderEmpty = () => (
<View style={styles.empty}>
<Text style={styles.emptyText}>No data available</Text>
</View>
);
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id.toString()}
ListHeaderComponent={renderHeader}
ListFooterComponent={renderFooter}
ListEmptyComponent={renderEmpty}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
colors={['#2196F3']}
tintColor="#2196F3"
/>
}
onEndReached={onEndReached}
onEndReachedThreshold={0.5}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={10}
initialNumToRender={10}
getItemLayout={(data, index) => ({
length: 80,
offset: 80 * index,
index,
})}
style={styles.container}
/>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
header: {
backgroundColor: '#2196F3',
padding: 20,
alignItems: 'center',
},
headerTitle: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
marginBottom: 5,
},
headerSubtitle: {
fontSize: 16,
color: 'rgba(255, 255, 255, 0.8)',
},
item: {
backgroundColor: 'white',
padding: 15,
marginHorizontal: 10,
marginVertical: 5,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
itemTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
marginBottom: 5,
},
itemSubtitle: {
fontSize: 14,
color: '#666',
marginBottom: 5,
},
itemTimestamp: {
fontSize: 12,
color: '#999',
},
footer: {
padding: 20,
alignItems: 'center',
},
footerText: {
marginTop: 10,
fontSize: 14,
color: '#666',
},
empty: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 40,
},
emptyText: {
fontSize: 16,
color: '#999',
},
});
export default AdvancedFlatList;