How to Implement Pagination in your Reactjs
Tags: webdev, javascript, react, programming
Published: 2023-08-22 18:40:48

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.


![Live Preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lg4nscww65de2gld97gw.gif)



## 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:

```bash
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:

1. **Data Storage:** Utilize the `useState` hook to store data fetched from the server. Initialize the state with an empty array.

2. **Loading Indicator:** Set up a `loading` state to notify users when data is being fetched. Initialize it as `false`.

3. **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 with `1`.

4. **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:

```jsx
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](https://jsonplaceholder.typicode.com/posts). Here's how you can handle the data fetching process:

1. **UseEffect for Fetching:** Create a `useEffect` to fetch data from the API. This ensures that data is fetched when the component mounts.

2. **Fetching Function:** Inside the `useEffect`, implement an `async` function using `fetch` to retrieve data from the API endpoint.

3. **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:

```jsx
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:

```jsx
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
```css
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:

1. **Calculating Pages:** Using a loop, determine the number of pages needed based on the data length and posts per page.

2. **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:

```jsx
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:

1. **Creating the Handler:** Define a function, such as `handlePagination`, in your `App.jsx` to update the `currentPage` state.

2. **Passing the Handler:** Pass the `handlePagination` function to the `Pagination` component as a prop.

3. **Using the Handler:** Inside the `Pagination` component, implement the `onClick` event for each page button. Call the `handlePagination` function with the appropriate page number.

```jsx
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:

1. **Conditional Class:** Inside the `Pagination` component's `map` function, conditionally apply a class to the active page's button.

```jsx
{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]( https://github.com/canhamzacode/pagination)

## 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]( http://twitter.com/canhamzacode)
- Facebook:[@Hamzat Abdul-muizz](https://web.facebook.com/abdulmuizz.hamzat) 
- Instagram: [@CanHamzaCode]( https://www.instagram.com/canhamzacode)  

Happy coding!

---