Pagination in React Native with Page

Hillary Okerio
3 min readJul 27, 2023

--

Introduction:

Pagination is a powerful technique in React Native that enables us to efficiently manage and display large lists of data. In this article, we’ll delve into implementing advanced pagination using FlatList and pagination buttons. We’ll discuss the logic behind pagination, how to fetch data for each page, and how to optimize the rendering process. Let’s dive in and master React Native pagination!

..... component structure ....
const handlePageClick = (p: number) => setCurrentPage(p);

const renderItem = ({item}: {item: ScoreCard}) => {
return <Card item={item} key={item.id} />;
};

return (
<SafeAreaView style={styles.container}>
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={item => item.id}
ListEmptyComponent={handleEmpty}
windowSize={10} // adds functionality of VirtualizedList
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
}
/>
<View style={styles.paginationContainer}>
{renderPaginationButtons()}
</View>
</SafeAreaView>
)
...
  1. Pagination Logic

At the core of our pagination implementation is the ‘Institution’ component. It utilizes React hooks, such as ‘useState’, to manage crucial state variables. The ‘currentPage’ state represents the current page being displayed, while ‘totalPages’ stores the total number of pages available for the entire list. We set ‘itemsPerPage’ to determine the number of items to display per page, optimizing the loading process.

const [totalPages, setTotalpages] = useState(0);
const [currentPage, setCurrentPage] = useState(0);
const [items, setItems] = useState([]);
const [refreshing, setRefreshing] = useState(false);
const itemsPerPage = 16;

2. Fetching Data for Each Page

The ‘fetchData’ function is a critical part of our pagination logic. When the ‘Institution’ component mounts or when the ‘currentPage’ changes, we call this function to retrieve the data for the current page. We use the ‘fetcher’ utility function, which handles data fetching from an API or any other source.

useEffect(() => {
fetchData();
}, [currentPage]);

async function fetchData() {
setRefreshing(true);
try {
let response = await fetcher(currentPage, itemsPerPage);
setTotalpages(response.metadata.total / itemsPerPage);
let data: [] = response.results;
setItems(data);
setRefreshing(false);
} catch (error) {
setRefreshing(false);
console.log(error);
}
}

3. Handling Pagination Buttons

To enable users to navigate through the paginated list, we render pagination buttons using TouchableOpacity elements. The ‘renderPaginationButtons’ function calculates which pages to display based on the ‘currentPage’, ‘totalPages’, and the desired maximum number of buttons (‘maxButtonsToShow’). It then generates the appropriate buttons.

const renderPaginationButtons = () => {
const maxButtonsToShow = 5;
let startPage = Math.max(0, currentPage - Math.floor(maxButtonsToShow / 2));
let endPage = Math.min(totalPages, startPage + maxButtonsToShow - 1);

if (endPage - startPage + 1 < maxButtonsToShow) {
startPage = Math.max(0, endPage - maxButtonsToShow + 1);
}

const buttons = [];

for (let i = startPage; i <= endPage; i++) {
buttons.push(
<TouchableOpacity
key={i}
onPress={() => handlePageClick(i)}
style={[
styles.paginationButton,
i === currentPage ? styles.activeButton : null,
]}>
<Text style={{color: 'white'}}>{i}</Text>
</TouchableOpacity>,
);
}

return buttons;
};

4. Pull-to-Refresh and Empty Data Handling

To provide a better user experience, we implement a pull-to-refresh functionality using ‘RefreshControl’. Users can manually refresh the list when needed. Additionally, we handle the scenario when there are no institutions to display by rendering a ‘No Institution’ message.

const handleRefresh = () => {
setRefreshing(true);
setTimeout(() => setRefreshing(false), 1000);
};

const handleEmpty = () => {
return <Text> No Institution!</Text>;
};

5. Styling for a Better User Experience

We utilize StyleSheet to add visual appeal to our components. The pagination buttons change color and size when active, providing visual feedback to users, enhancing the overall app experience.

const styles = StyleSheet.create({
container: {
flex: 1,
},
paginationContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 8,
backgroundColor: 'transparent',
},
paginationButton: {
justifyContent: 'center',
alignItems: 'center',
width: 40,
height: 40,
borderRadius: 20,
marginHorizontal: 4,
backgroundColor: 'gray',
},
activeButton: {
backgroundColor: '#22c55d',
width: 50,
height: 50,
borderRadius: 25,
},
buttonText: {
color: 'white',
},
});

Conclusion

Link to this code can be found here -> paginate. By mastering React Native pagination with FlatList and pagination buttons, we can effortlessly handle large lists of data, ensuring smooth performance and a better user experience. Pagination significantly optimizes rendering, reduces network resource load, and improves overall app responsiveness. Implementing advanced pagination in React Native applications is a valuable skill for delivering high-quality and performant mobile apps.

--

--