React Native SectionList - Complete Guide with Examples
Last update: 2025-04-24The SectionList component in React Native is a powerful tool for displaying sectioned data in a scrollable list. In this quick win, we’ll explore how to implement and customize SectionList with practical examples and best practices.
Basic SectionList Implementation
The SectionList component requires a specific data structure where each section must have a title
and a data
array. Let’s start with a simple SectionList implementation that groups food items by category:
import React from 'react';
import { View, Text, SectionList, StyleSheet } from 'react-native';
const BasicSectionList = () => {
// Each section must have a title and a data array
// The data array contains the items for that section
const DATA = [
{
title: 'Fruits',
data: ['Apple', 'Banana', 'Orange', 'Mango']
},
{
title: 'Vegetables',
data: ['Carrot', 'Broccoli', 'Spinach']
},
{
title: 'Dairy',
data: ['Milk', 'Cheese', 'Yogurt']
}
];
return (
<SectionList
sections={DATA} // Your sectioned data array
keyExtractor={(item, index) => item + index} // Unique key for each item
renderItem={({ item }) => (
// How each list item should be rendered
<View style={styles.item}>
<Text style={styles.itemText}>{item}</Text>
</View>
)}
renderSectionHeader={({ section: { title } }) => (
// How each section header should be rendered
<View style={styles.header}>
<Text style={styles.headerText}>{title}</Text>
</View>
)}
/>
);
};
// Styles to make our list look clean and organized
const styles = StyleSheet.create({
item: {
padding: 15,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#eee'
},
itemText: {
fontSize: 16
},
header: {
padding: 15,
backgroundColor: '#f4f4f4'
},
headerText: {
fontSize: 18,
fontWeight: 'bold'
}
});
export default BasicSectionList;
The SectionList component requires several key props:
sections
: An array of objects containing your sectioned datarenderItem
: A function that returns the UI for each item in a sectionrenderSectionHeader
: A function that returns the UI for each section headerkeyExtractor
: A function to generate unique keys for list items
Advanced Features
1. Custom Item Separators
Separators help distinguish between items and sections visually. You can customize both item separators (between items in a section) and section separators (between different sections):
const AdvancedSectionList = () => {
// Custom separator component for items within a section
const renderSeparator = () => <View style={styles.separator} />;
return (
<SectionList
// ... other props from basic example
ItemSeparatorComponent={renderSeparator} // Renders between items within sections
SectionSeparatorComponent={() => (
// Renders between sections
<View style={styles.sectionSeparator} />
)}
/>
);
};
const styles = StyleSheet.create({
separator: {
height: 1,
backgroundColor: '#e0e0e0' // Light gray line between items
},
sectionSeparator: {
height: 2,
backgroundColor: '#f0f0f0' // Slightly thicker line between sections
}
});
2. Pull to Refresh
Pull-to-refresh is a common pattern in mobile apps that allows users to update the list content by pulling down. Here’s how to implement it with proper loading states:
const RefreshableSectionList = () => {
const [refreshing, setRefreshing] = useState(false); // Track refresh state
const [data, setData] = useState(initialData);
const onRefresh = async () => {
setRefreshing(true); // Show the refresh spinner
try {
// Simulate or make an actual API call
const newData = await fetchNewData();
setData(newData); // Update the list with new data
} catch (error) {
console.error('Error refreshing:', error);
// You might want to show an error message to the user here
}
setRefreshing(false); // Hide the refresh spinner
};
return (
<SectionList
sections={data}
refreshing={refreshing} // Controls the refresh spinner
onRefresh={onRefresh} // Called when the user pulls to refresh
// ... other props
/>
);
};
3. Sticky Headers
Sticky headers remain visible at the top of the list while scrolling through their section, improving navigation and context:
<SectionList
sections={DATA}
stickySectionHeadersEnabled={true} // iOS is true by default, Android needs this prop
// ... other props
/>
Working with Complex Data
Real-world applications often need to display more complex data structures. Here’s an example of a user list with online/offline status:
const ComplexSectionList = () => {
// Complex data structure with nested objects
const COMPLEX_DATA = [
{
title: 'Online Users',
data: [
{ id: 1, name: 'John Doe', status: 'active', lastSeen: 'now' },
{ id: 2, name: 'Jane Smith', status: 'active', lastSeen: 'now' }
]
},
{
title: 'Offline Users',
data: [
{ id: 3, name: 'Mike Johnson', status: 'inactive', lastSeen: '2h ago' },
{ id: 4, name: 'Sarah Wilson', status: 'inactive', lastSeen: '1d ago' }
]
}
];
// Custom render function for complex items
const renderItem = ({ item }) => (
<View style={styles.complexItem}>
<Text style={styles.userName}>{item.name}</Text>
<View style={styles.userInfo}>
{/* Use emojis as status indicators */}
<Text style={styles.status}>{item.status === 'active' ? '🟢' : '⚫️'}</Text>
<Text style={styles.lastSeen}>{item.lastSeen}</Text>
</View>
</View>
);
return (
<SectionList
sections={COMPLEX_DATA}
keyExtractor={(item) => item.id.toString()} // Use unique IDs for keys
renderItem={renderItem}
renderSectionHeader={({ section: { title } }) => (
<View style={styles.complexHeader}>
<Text style={styles.complexHeaderText}>{title}</Text>
</View>
)}
/>
);
};
// Enhanced styles for complex data display
const styles = StyleSheet.create({
complexItem: {
padding: 15,
flexDirection: 'row', // Horizontal layout
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: '#fff'
},
userName: {
fontSize: 16,
fontWeight: '500'
},
userInfo: {
flexDirection: 'row',
alignItems: 'center'
},
status: {
marginRight: 8
},
lastSeen: {
color: '#666',
fontSize: 14
},
complexHeader: {
padding: 15,
backgroundColor: '#f8f8f8',
borderBottomWidth: 1,
borderBottomColor: '#eee'
},
complexHeaderText: {
fontSize: 18,
fontWeight: 'bold',
color: '#333'
}
});
Performance Optimization
Large lists can impact performance. Here’s how to optimize your SectionList for better performance:
const OptimizedSectionList = () => {
// Memoize the render function to prevent unnecessary re-renders
const renderItem = useCallback(
({ item }) => (
<View style={styles.item}>
<Text>{item}</Text>
</View>
),
[] // Empty dependency array since render doesn't depend on props/state
);
// Pre-calculate dimensions for fixed-height items
// This helps SectionList optimize rendering
const getItemLayout = (data, index) => ({
length: 50, // Fixed height of each item
offset: 50 * index, // Position of each item
index
});
return (
<SectionList
sections={DATA}
renderItem={renderItem}
getItemLayout={getItemLayout}
initialNumToRender={10} // Number of items to render initially
maxToRenderPerBatch={10} // Number of items to render per batch
windowSize={5} // Number of screens worth of content to render
// ... other props
/>
);
};
Best Practices
Performance
- Use
getItemLayout
for fixed-height items - Implement
useCallback
for render functions - Optimize
initialNumToRender
andmaxToRenderPerBatch
- Use
User Experience
- Add loading indicators
- Implement pull-to-refresh
- Use sticky headers when appropriate
- Add proper error handling
Data Management
- Keep data structures consistent
- Handle empty sections gracefully
- Implement proper key extraction
Styling
- Use consistent styling across sections
- Consider platform-specific designs
- Implement proper spacing and separators
Common Use Cases
- Contact lists with alphabetical sections
- Settings screens with grouped options
- Product catalogs with categories
- Chat applications with message grouping
- Timeline views with date-based sections
Summary
SectionList is a versatile component that helps organize and display sectioned data efficiently in React Native applications. By following these patterns and implementing the features discussed, you can create polished and performant sectioned lists.
Key takeaways:
- Structure your data properly with sections
- Customize headers and separators
- Implement performance optimizations
- Follow best practices for smooth user experience
- Handle complex data structures effectively
Now you’re ready to implement beautiful sectioned lists in your React Native apps! 🚀