usePaginationLoading saved progress…

usePagination

Any list longer than a screen gets paginated, and the page-math is easy to get almost right — off-by-one page counts, a "Next" button that walks past the last page, indices that slice the wrong slice. usePagination centralizes it: give it a total count and a pageSize, and it hands back the current page, the pageCount, movement controls that clamp to valid pages, and the array indices to slice the current page's items.

Implement usePagination({ total, pageSize = 10, initialPage = 1 }). Return page, pageCount, setPage/next/prev/first/last (all clamped), hasPrev/hasNext, and startIndex/endIndex for a half-open slice.

Signature

function usePagination({ total, pageSize = 10, initialPage = 1 }) {
  // returns { page, pageCount, setPage, next, prev, first, last,
  //           hasPrev, hasNext, startIndex, endIndex }
}

Examples

const { page, pageCount, next, prev, startIndex, endIndex } =
  usePagination({ total: users.length, pageSize: 20 });

const visible = users.slice(startIndex, endIndex);
// "Page {page} of {pageCount}"
const p = usePagination({ total: 25, pageSize: 10 }); // pageCount = 3
p.setPage(999); // clamped -> page 3
p.next();       // stays 3 (already last)

Notes

  • pageCountMath.ceil(total / pageSize), but never less than 1 (an empty list is still "page 1 of 1").
  • Everything clampsnext/prev/setPage/first/last must keep page inside [1, pageCount].
  • Half-open indicesstartIndex = (page - 1) * pageSize, endIndex = min(startIndex + pageSize, total), so slice(startIndex, endIndex) gives the (possibly short) last page.
  • Survive a shrinking total — if total drops so the current page no longer exists, the reported page must fall back into range.
Loading editor…