40 - Pagination for Long Lists of Data

Description

Implement pagination to divide lengthy lists of data into multiple, manageable pages, enhancing user experience and performance.

  • Displays a limited number of items per page.

  • Provides navigation controls for users to move between pages.

  • Visually indicates the current page and total number of pages.

  • Optionally offers features like:

    • "Load More" buttons for infinite scrolling.

    • Jump-to-page selections for direct navigation.

Algorithm

  1. Component Structure:

    • Define a functional component named PaginatedList.

    • Accept props for:

      • items: Array of data items to display.

      • itemsPerPage: Number of items to display per page (default to 10).

      • onPageChange: Function to handle page change events.

    • Maintain internal state for:

      • currentPage: Index of the currently displayed page.

  2. Data Slicing:

    • Use array slicing to extract the appropriate items for the current page: const currentPageItems = items.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);

  3. Rendering Page Content:

    • Render the currentPageItems within the component.

  4. Pagination Controls:

    • Create navigation buttons or links for:

      • "Previous" page (if applicable).

      • "Next" page (if applicable).

      • Specific page numbers (optional).

      • "Load More" button (optional).

    • Update currentPage state when a navigation control is clicked.

    • Call the onPageChange prop function with the new page number.

Code

import React, { useState } from 'react';

const PaginatedList = ({ items, itemsPerPage = 10, onPageChange }) => {
  const [currentPage, setCurrentPage] = useState(1);

  const totalPages = Math.ceil(items.length / itemsPerPage);

  const handlePageChange = (newPage) => {
    if (newPage > 0 && newPage <= totalPages) {
      setCurrentPage(newPage);
      if (onPageChange) onPageChange(newPage);
    }
  };

  const renderPaginationControls = () => {
    const pageNumbers = [];
    for (let i = 1; i <= totalPages; i++) {
      pageNumbers.push(
        <button
          key={i}
          onClick={() => handlePageChange(i)}
          className={`page-number ${currentPage === i ? 'active' : ''}`}
        >
          {i}
        </button>
      );
    }
    return (
      <div className="pagination-controls">
        <button onClick={() => handlePageChange(currentPage - 1)} disabled={currentPage === 1}>
          Previous
        </button>
        {pageNumbers}
        <button onClick={() => handlePageChange(currentPage + 1)} disabled={currentPage === totalPages}>
          Next
        </button>
      </div>
    );
  };

  const renderItemList = () => {
    const startIndex = (currentPage - 1) * itemsPerPage;
    const endIndex = startIndex + itemsPerPage;
    return items.slice(startIndex, endIndex).map((item) => (
      <ListItem key={item.id} item={item} /> // Customize the list item rendering based on your data
    ));
  };

  return (
    <div className="paginated-list">
      {renderItemList()}
      {totalPages > 1 && renderPaginationControls()}
    </div>
  );
};

export default PaginatedList;

Explanation

  • State management: Tracks the current page number using useState.

  • Data slicing: Uses array.slice to extract the items for the current page.

  • Pagination controls: Renders buttons for navigating between pages and displays the current page number.

  • Optional features: You can further customize this code to include "Load More" buttons or jump-to-page options.

  • Integration with backend: Connect this component with your backend logic to fetch data in chunks based on the current page.

Additional Notes

  • This is a basic example and can be enhanced with styling, loading indicators, and error handling.

  • Consider accessibility features like keyboard navigation for pagination controls.

  • Utilize CSS media queries to adapt the pagination layout for different screen sizes.

Last updated