JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeQuestionsreact
PrevNext

Learn the concept

Advanced Patterns

react
senior
patterns

How would you design and implement a reusable Pagination component in React?

pagination
component-design
accessibility
patterns
machine-coding
Quick Answer

A reusable Pagination component manages page state, renders page numbers with ellipsis for large ranges, and exposes both controlled and uncontrolled APIs. It should include keyboard navigation, ARIA attributes for accessibility, and integrate cleanly with server-side pagination endpoints.

Detailed Explanation

Component API Design:

  • totalItems / totalPages — total count from the data source
  • pageSize — items per page (often configurable)
  • currentPage (controlled) or defaultPage (uncontrolled) — active page
  • onPageChange — callback when page changes
  • siblingCount — how many page numbers to show around the current page
  • boundaryCount — how many page numbers to show at the start and end

Page Range Algorithm:

  • The core challenge is generating [1, '...', 4, 5, 6, '...', 20] from the current page and total pages
  • Show first and last pages always (boundary)
  • Show pages adjacent to the current page (siblings)
  • Insert ellipsis ('...') when there are gaps
  • Handle edge cases: few total pages, current page near start or end

Accessibility (ARIA):

  • Use <nav aria-label="Pagination"> as the wrapper
  • Use <ol> / <ul> for the page list
  • Mark the current page with aria-current="page"
  • Disable prev/next buttons at boundaries with aria-disabled
  • Provide aria-label on each button (e.g., "Go to page 5")
  • Support keyboard navigation: Tab between buttons, Enter/Space to activate

Controlled vs Uncontrolled:

  • Controlled: Parent manages currentPage state and passes it as a prop. Component calls onPageChange but does not update internally.
  • Uncontrolled: Component manages its own page state with defaultPage as the initial value.

Server-Side Pagination:

  • Server returns { data, total, page, pageSize }
  • Calculate totalPages = Math.ceil(total / pageSize)
  • Pass totalPages and currentPage to the Pagination component
  • On page change, fetch new data from the server

Code Examples

Page range algorithm with ellipsisJavaScript
function generatePageRange({ currentPage, totalPages, siblingCount = 1 }) {
  const ELLIPSIS = '...';

  function range(start, end) {
    return Array.from({ length: end - start + 1 }, (_, i) => start + i);
  }

  // Total slots: first + last + current + 2*siblings + 2*ellipsis
  const totalSlots = siblingCount * 2 + 5;

  // Case 1: Total pages fit within slots — no ellipsis
  if (totalPages <= totalSlots) {
    return range(1, totalPages);
  }

  const leftSibling = Math.max(currentPage - siblingCount, 1);
  const rightSibling = Math.min(currentPage + siblingCount, totalPages);

  const showLeftEllipsis = leftSibling > 2;
  const showRightEllipsis = rightSibling < totalPages - 1;

  // Case 2: No left ellipsis, show right ellipsis
  if (!showLeftEllipsis && showRightEllipsis) {
    const leftRange = range(1, 3 + siblingCount * 2);
    return [...leftRange, ELLIPSIS, totalPages];
  }

  // Case 3: Show left ellipsis, no right ellipsis
  if (showLeftEllipsis && !showRightEllipsis) {
    const rightRange = range(totalPages - (2 + siblingCount * 2), totalPages);
    return [1, ELLIPSIS, ...rightRange];
  }

  // Case 4: Both ellipsis
  const middleRange = range(leftSibling, rightSibling);
  return [1, ELLIPSIS, ...middleRange, ELLIPSIS, totalPages];
}

// Examples:
// currentPage=1,  totalPages=20 => [1, 2, 3, 4, 5, '...', 20]
// currentPage=10, totalPages=20 => [1, '...', 9, 10, 11, '...', 20]
// currentPage=20, totalPages=20 => [1, '...', 16, 17, 18, 19, 20]
// currentPage=3,  totalPages=5  => [1, 2, 3, 4, 5]

Real-World Applications

Use Cases

E-Commerce Product Listings

Paginating large product catalogs with server-side pagination, displaying page numbers and total result counts while keeping URLs shareable via query parameters

Admin Dashboard Tables

Paginating data tables with configurable page sizes, column sorting, and server-side filtering, where the pagination component coordinates with multiple data controls

Search Results Pages

Displaying paginated search results with ellipsis for large result sets, deep linking support so users can share or bookmark specific result pages

Mini Projects

Full-Featured Data Table

advanced

Build a reusable data table component with pagination, sortable columns, row selection, and configurable page sizes integrated with a mock REST API

URL-Synced Pagination

intermediate

Create a pagination component that reads from and writes to URL search parameters, supports browser back/forward navigation, and works with Next.js App Router

Industry Examples

Shadcn/ui

Provides a composable Pagination component built on Radix primitives with full accessibility support and Tailwind styling

MUI (Material UI)

Offers a production Pagination component with controlled/uncontrolled modes, custom rendering, and integration with their DataGrid for table pagination

Resources

WAI-ARIA Practices - Pagination

docs

Shadcn/ui Pagination

docs

Related Questions

How do you ensure accessibility (a11y) in React applications?

mid
accessibility
Previous
What security vulnerabilities should you address in React applications and how do you prevent them?
Next
How does list virtualization (windowing) work in React and when should you use it?
PrevNext