Pagination is a technique that involves breaking down a large dataset into manageable segments or pages. It's a crucial component when dealing with lists, tables, or search results to ensure a smooth user experience. By dividing content into pages and providing navigation controls, users can access information more effectively without feeling overwhelmed.
Why Use Pagination?
In this article, we'll guide you through implementing pagination in your ReactJS application. By incorporating pagination, you'll significantly enhance your users' experience, achieve faster loading times, and simplify navigation within your web app or website. This tutorial assumes familiarity with JavaScript and ReactJS, making it accessible to developers of varying skill levels.
Getting Started
Before we dive into creating pagination, make sure you have a ReactJS app set up. If you're starting from scratch, you can create a new app using the following command:
yarn create vite
Once your server is running, your directory structure should resemble the one shown below.
project-root/
├── src/
│ ├── App.jsx
│ ├── components/
│ ├── ...
Implementing Pagination Logic
We'll begin by focusing on the App.jsx
file within the src
directory. This is where the core pagination logic will be implemented. Here are the key steps:
Data Storage: Utilize the
useState
hook to store data fetched from the server. Initialize the state with an empty array.Loading Indicator: Set up a
loading
state to notify users when data is being fetched. Initialize it asfalse
.Current Page Management: Create a
currentPage
state to keep track of the currently displayed page. If you're working with 100 items and want to show 10 per page, initialize this state with1
.Posts Per Page: Implement a state to manage the number of posts displayed per page. In this article, we'll consider 10 posts per page.
Here's a snippet illustrating these states:
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage, setPostsPerPage] = useState(10);
Fetching Data from the Server
To simulate fetching data, we'll use a fake API provided by jsonplaceholder.typicode.com. Here's how you can handle the data fetching process:
UseEffect for Fetching: Create a
useEffect
to fetch data from the API. This ensures that data is fetched when the component mounts.Fetching Function: Inside the
useEffect
, implement anasync
function usingfetch
to retrieve data from the API endpoint.Updating State: Set the
posts
state to the fetched data. Don't forget to handle loading states appropriately.
Here's a snippet showcasing this process:
useEffect(() => {
const fetchPosts = async () => {
setLoading(true);
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
const data = await response.json();
setPosts(data);
setLoading(false);
} catch (error) {
console.log(error);
}
};
fetchPosts();
}, []);
Displaying Paginated Data
To display paginated data, we'll create a Post
component. This component will receive the posts
array and the loading
state as props. Here's how you can structure the Post
component:
import React from 'react';
const Post = ({ posts, loading }) => {
if (loading) {
return <h1>Loading...</h1>;
}
return (
<>
{posts.map((data, index) => (
<div className='list' key={index}>
<p>{data.title}</p>
</div>
))}
</>
);
};
export default Post;
To make it look more appealing I have a simple css file used for this article
body {
background: black;
color: white;
}
.container {
width: 100%;
max-width: 800px;
margin: auto;
}
.list {
border: 1px solid #fff;
padding: 5px;
}
.pagination {
display: flex;
border: 1px solid #fff;
justify-content: space-between;
padding: 20px;
}
.pagination button {
padding: 10px;
}
.active {
background: black;
color: #fff;
border: 1px solid #fff;
}
Implementing the Pagination Component
To control the page navigation, let's create a Pagination
component. This component will calculate the number of pages based on the data length and posts per page. Here's the process:
Calculating Pages: Using a loop, determine the number of pages needed based on the data length and posts per page.
Rendering Page Numbers: Render buttons with page numbers for navigation. We'll utilize the
map
function to create buttons for each page.
Here's a simplified version of the Pagination
component:
import React from 'react';
const Pagination = ({ postsPerPage, length }) => {
const paginationNumbers = [];
for (let i = 1; i <= Math.ceil(length / postsPerPage); i++) {
paginationNumbers.push(i);
}
return (
<div className='pagination'>
{paginationNumbers.map((pageNumber) => (
<button key={pageNumber}>{pageNumber}</button>
))}
</div>
);
};
export default Pagination;
Handling Page Changes
To make the pagination dynamic, we need a way to handle page changes. This involves updating the currentPage
state. Here's how you can achieve this:
Creating the Handler: Define a function, such as
handlePagination
, in yourApp.jsx
to update thecurrentPage
state.Passing the Handler: Pass the
handlePagination
function to thePagination
component as a prop.Using the Handler: Inside the
Pagination
component, implement theonClick
event for each page button. Call thehandlePagination
function with the appropriate page number.
const handlePagination = (pageNumber) => {
setCurrentPage(pageNumber);
};
// Inside your component's return...
<Pagination
length={posts.length}
postsPerPage={postsPerPage}
handlePagination={handlePagination}
/>
Highlighting the Active Page
For better user experience, highlight the currently active page. To achieve this, add a dynamic class to the active page's button. Here's how:
-
Conditional Class: Inside the
Pagination
component'smap
function, conditionally apply a class to the active page's button.
{paginationNumbers.map((pageNumber) => (
<button
key={pageNumber}
className={currentPage === pageNumber ? 'active' : ''}
>
{pageNumber}
</button>
))}
Conclusion
Congratulations! You've successfully implemented pagination in your ReactJS application. By breaking down data into manageable chunks and providing intuitive navigation controls, you've enhanced both the user experience and your app's performance. Feel free to explore further customization and experiment with different designs to create an even more engaging interface for your users. Link to the source code used in this article here
Feedback and Interaction
If you found this article helpful or have any feedback, I'd love to hear from you! Feel free to connect with me on social media and share your thoughts:
- Twitter: @CanHamzaCode
- Facebook:@Hamzat Abdul-muizz
- Instagram: @CanHamzaCode
Happy coding!
Top comments (1)
nice one!