Pagination in React with implementation
Tags: react, javascript, frontend, webdev
Published: 2023-08-12 19:47:15

_Pagination_ is a technique used in web development to divide a large set of content or data into smaller, more manageable sections or pages. This allows users to navigate through the content in a structured and organized manner, preventing overwhelming them with a single, long list of items.

In a web context, pagination is commonly used for displaying lists of items such as articles, products, search results, or comments. Instead of loading and displaying all items at once, pagination breaks them down into smaller chunks, or "pages," which are presented one at a time. Users can then navigate through these pages using navigation controls like "Previous" and "Next" buttons or numbered page links.

Key components of pagination include:

1. Page Size: The number of items displayed on a single page. This can be a fixed number or a user-configurable option.

2. Total Items: The total number of items available in the dataset. This is used to calculate the total number of pages.

3. Current Page: The page is currently being displayed to the user.

4. Navigation Controls: Buttons or links that allow users to move between pages, such as "Previous" and "Next" buttons, as well as numbered page links.

5. Ellipsis: An ellipsis (...) is often used to indicate that there are more pages in between when there are too many pages to display all at once. For example, "1 2 ... 10 11 12 ... 20."

6. Data Fetching: When users navigate to a new page, the data corresponding to that page is fetched from the server (or from local data) and displayed.

Pagination helps improve the user experience by making content more accessible and easier to navigate. It reduces loading times and the cognitive load on users, making it especially useful when dealing with large sets of data.

## Implementation in React:

```javascript
import "./styles.css";

import { useState, useEffect } from "react";

export default function App() {
  const [products, setProducts] = useState([]);
  const [page, setPage] = useState(1);

  const fetchProducts = async () => {
    const res = await fetch("https://dummyjson.com/products?limit=100");
    const data = await res.json();
    if (data.products && data.products.length) setProducts(data.products);
  };

  useEffect(() => {
    fetchProducts();
  }, []);

// event handler for page change on click
  const handlePageChange = (pageNumber) => {
    if (
      pageNumber > 0 &&
      pageNumber <= products.length / 10 &&
      pageNumber !== page
    )
      setPage(pageNumber);    
  };

  return (
    <div className="App">
      <h1>All Products</h1>
      {products.length && (
        <ol className="All__products">
          {products.slice(page * 10 - 10, page * 10).map((product) => (
            <li key={product.id} className="product">
              <img src={product.thumbnail} alt={product.title} />
              <h4>{product.title}</h4>
            </li>
          ))}
        </ol>
      )}

      {products.length > 0 && (
        <section className="pagination">
          <span
            onClick={() => handlePageChange(page - 1)}
            className={`arrow ${page === 1 ? "pagination__disabled" : ""}`}
          >
            ⬅
          </span>
          {[...Array(Math.floor(products.length / 10))].map((_, i) => (
            <span
              className={`page__number ${
                page === i + 1 ? "selected__page__number" : ""
              }`}
              key={i + 1}
              onClick={() => handlePageChange(i + 1)}
            >
              {i + 1}
            </span>
          ))}
          <span
            onClick={() => handlePageChange(page + 1)}
            className={`arrow ${
              page === Math.floor(products.length / 10)
                ? "pagination__disabled"
                : ""
            }`}
          >
            ➡
          </span>
        </section>
      )}
    </div>
  );
}
```
[Codesandbox](codesandbox)
## Output

![Pagination output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4nn93cf5jr02s2gm5mlj.gif)

## Working
Let's break down the provided code step by step to understand its functionality:

**1. Import Statements:** The code starts by importing the necessary modules and styles. The useState and useEffect hooks from the react package are used for managing state and performing side effects.

**2. State Initialization:** Two pieces of state are initialized using the useState hook:

- products: An array that will store the fetched products.

- page: A number that represents the current page of products to display.

**3. Fetching Products:** The fetchProducts function is defined using the async/await pattern to fetch data from an API endpoint (dummyjson.com/products?limit=100). The fetched products are set in the products state using the setProducts function.

**4. Use Effect Hook:** The useEffect hook is used to fetch products when the component mounts. The empty dependency array ([]) ensures that the effect runs only once when the component is mounted. Inside this we are fetching the products once.

**5. Handle Page Change:** The handlePageChange function takes a pageNumber argument and updates the page state only if the provided page number is within valid limits (greater than 0, less than or equal to the calculated total pages, and not equal to the current page).

**6. Rendering Products:** Inside the JSX, the component first renders a heading "All Products". It then conditionally renders a list of products inside an ordered list with the class All__products. The products are displayed using the slice method based on the current page and items per page to display the products in chunk.


**7. Pagination Controls:** If there are products available, a pagination section is rendered. It consists of:

- A "Previous" arrow (<-) that is clickable if the current page is greater than 1.

- The expression [...Array(Math.floor(products.length / 10))] is used to generate an array with a length that represents the number of pagination elements needed based on the total number of products.

- A series of page numbers is generated using the map function. The page numbers are clickable, and the currently selected page is highlighted with the selected__page__number class.

- A "Next" arrow (->) that is clickable if the current page is not the last page.

Pagination control elements have click handlers that invoke the handlePageChange function with appropriate arguments to change the page.

In conclusion, pagination is a crucial web development technique that enhances user experience by dividing extensive content into manageable sections. This facilitates structured navigation and prevents overwhelming displays. Commonly used for various lists, such as articles, products, or search results, pagination divides content into pages with controls like "Previous" and "Next" buttons. The React code example demonstrates dynamic product pagination, utilizing useState for state management and useEffect for fetching data. The rendered products are chunked based on the current page, with intuitive pagination controls. This technique offers a user-friendly approach, particularly when handling extensive datasets, thus streamlining content consumption.

Hope you Iiked it, If yes then give a like. Thanks for reading.

Check this one out: [Why we should not mutate state in react](https://dev.to/endeavourmonk/why-we-should-not-mutate-in-react-18ej)

Or this one: [Endeavour Monk Youtube](https://www.youtube.com/@endeavourmonk)