Mobile apps often deal with large lists of data, whether it's social media feeds, product catalogs, or search results. Displaying all this information at once leads to slow loading times, poor performance, and a frustrating user experience. This is where pagination comes in – a technique that loads and displays data in chunks, making your app feel smooth and responsive.
This article will explore implementing pagination in
React Native (RN) using the versatile
FlatList
component. We'll use the
https://jsonplaceholder.typicode.com/photos
API to display a
paginated gallery of images, focusing on handling the case when we reach the
end of the data correctly.
Why Pagination Matters
Imagine scrolling through thousands of products in an e-commerce app. Without pagination, the app would try to load everything simultaneously, causing:
- Slow initial loading: Users face a blank screen while the app fetches and renders the entire dataset.
- Performance issues: Scrolling becomes laggy, especially on less powerful devices.
- Increased data usage: Downloading unnecessary data wastes bandwidth.
Pagination solves these problems by:
- Fetching data in manageable chunks: Only the initial items are loaded, improving loading times.
- Optimizing rendering: The app renders a limited number of items at a time, ensuring smooth scrolling.
- Reducing data usage: Data is loaded on demand, conserving bandwidth.
Implementing Pagination with FlatList in RN
React Native's FlatList
is excellent for building performant
lists with built-in pagination support. Let's break down the process:
1. Setting up the Project:
If you haven't already, create a new React Native project:
npx expo init MyPaginationApp
cd MyPaginationApp
2. Building the FlatList with Accurate End-of-Data Handling:
Here's our App.js
file with comments explaining the pagination
logic:
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, StyleSheet, Image, ActivityIndicator } from 'react-native';
const App = () => {
const limit = 20;
const [photos, setPhotos] = useState([]); // Store fetched photos
const [page, setPage] = useState(1); // Current page number
const [isLoading, setIsLoading] = useState(false); // Loading state
const [isEndOfData, setIsEndOfData] = useState(false); // Flag for end of data
useEffect(() => {
fetchPhotos();
}, [page]); // Fetch photos whenever 'page' changes
const fetchPhotos = async () => {
if (isLoading || isEndOfData) return; // Don't fetch if already loading or at the end
setIsLoading(true);
try {
console.log('page:', page);
const response = await fetch(
`https://jsonplaceholder.typicode.com/photos?_page=${page}&_limit=${limit}`
);
const data = await response.json();
// Correct condition for end of data:
if (data.length < limit) {
setIsEndOfData(true);
} else {
setPhotos(prevPhotos => [...prevPhotos, ...data]);
}
} catch (error) {
console.error('Error fetching photos:', error);
} finally {
setIsLoading(false);
}
};
const renderItem = ({ item }) => (
<View style={styles.item}>
<Image source={{ uri: item.thumbnailUrl }} style={styles.thumbnail} />
<Text>{item.title}</Text>
</View>
);
const handleLoadMore = () => {
if (!isLoading) {
setPage(page + 1); // Increment page to load next set
}
};
const renderFooter = () => {
if (isEndOfData) {
return (
<View style={styles.endMessage}>
<Text>End of Gallery</Text>
</View>
);
} else if (isLoading) {
return (
<View style={styles.loader}>
<ActivityIndicator size="large" />
</View>
);
} else {
return null;
}
};
return (
<View style={styles.container}>
<FlatList
data={photos}
renderItem={renderItem}
keyExtractor={item => item.id.toString()}
onEndReached={handleLoadMore}
onEndReachedThreshold={0.5}
ListFooterComponent={renderFooter} // Render footer
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
item: {
marginVertical: 8,
alignItems: 'center'
},
thumbnail: {
width: 100,
height: 100,
marginBottom: 5,
},
});
export default App;
3. Running the App:
Start your React Native application:
npm run android // For Android
npm run ios // For iOS
Now you have a robustly paginated gallery that accurately handles the end of the data, providing a smooth and user-friendly experience.
Comments
Post a Comment