Pagination Guide

This library supports both client-side and server-side pagination strategies. Client-side pagination loads all data upfront and handles paging in the browser, while server-side pagination fetches data per page from your backend.

Examples & API

Guide

QUI Pagination Hook

QUI provides useTablePagination to simplify connecting table pagination state to the @qualcomm-ui/react/pagination component.

import {useTablePagination} from "@qualcomm-ui/react/table"

const paginationProps = useTablePagination(table, {
  totalCount: 1000, // for manual pagination, provide total row count from your backend response
})

// render pagination UI in your table component
return (
  <Table.Root>
    <Table.ScrollContainer>
      <Table.Table>{/*...*/}</Table.Table>
    </Table.ScrollContainer>
    <Table.Pagination {...paginationProps} />
  </Table.Root>
)

The hook returns props compatible with QUI's Pagination component, handling the conversion between table state (zero-indexed pageIndex) and pagination UI (one-indexed page numbers).

Client-Side Pagination

Client-side pagination loads all data upfront. The table instance handles page logic in the browser.

When to Use Client-Side Pagination

Consider client-side pagination when:

  • You can afford to load all data upfront
  • Dataset size is acceptable (~10k rows or less)
  • You are not dependent on backend sorting, filtering, or pagination

Performance degrades with large datasets due to memory constraints and initial load time. Consider server-side pagination for datasets larger than 10,000 rows.

Setup Client-Side Pagination

Enable client-side pagination by providing the pagination row model:

import {getCoreRowModel, getPaginationRowModel} from "@qualcomm-ui/core/table"
import {useReactTable} from "@qualcomm-ui/react/table"

const table = useReactTable({
  columns,
  data,
  getCoreRowModel: getCoreRowModel(),
  getPaginationRowModel: getPaginationRowModel(),
})

Server-Side Pagination

Server-side pagination fetches only the data needed for the current page.

Setup Manual Pagination

Set manualPagination: true to indicate that the data you provide is already paginated. The pagination row model is not needed for server-side pagination.

const table = useReactTable({
  columns,
  data, // already paginated by your backend
  getCoreRowModel: getCoreRowModel(),
  manualPagination: true,
  pageCount: totalPages, // provide total page count
})

Page Count

Provide pageCount so the table knows the total number of pages. If you don't know the total count, pass -1 for pageCount. This disables accurate "last page" detection, causing getCanNextPage() to always return true.

const table = useReactTable({
  columns,
  data,
  getCoreRowModel: getCoreRowModel(),
  manualPagination: true,
  pageCount: apiResponse.totalPages,
})

Pagination State

The pagination state contains:

  • pageIndex: Current page (zero-indexed)
  • pageSize: Number of rows per page

Controlled State

Manage pagination state in your component to respond to page changes:

const [pagination, setPagination] = useState({
  pageIndex: 0,
  pageSize: 10,
})

const table = useReactTable({
  columns,
  data,
  getCoreRowModel: getCoreRowModel(),
  getPaginationRowModel: getPaginationRowModel(),
  onPaginationChange: setPagination,
  pageCount: apiResponse.totalPages,
  state: {pagination},
})

For server-side pagination, trigger data fetching when pagination state changes:

useEffect(() => {
  fetchData({
    page: pagination.pageIndex,
    pageSize: pagination.pageSize,
  })
}, [pagination])

Initial State

Use initialState to set default values without managing state:

const table = useReactTable({
  columns,
  data,
  getCoreRowModel: getCoreRowModel(),
  getPaginationRowModel: getPaginationRowModel(),
  initialState: {
    pagination: {
      pageIndex: 0,
      pageSize: 25,
    },
  },
})

Do not pass pagination to both state and initialState. The state option overrides initialState.

Pagination Options

Auto Reset Page Index

By default, pageIndex resets to 0 when data changes, filters update, or other page-altering state changes occur. This behavior is disabled automatically when manualPagination: true, but can be controlled with autoResetPageIndex:

const table = useReactTable({
  columns,
  data,
  getCoreRowModel: getCoreRowModel(),
  getPaginationRowModel: getPaginationRowModel(),
  autoResetPageIndex: false, // prevent reset on data changes
})

Disabling auto-reset requires handling page index resets manually to avoid empty pages when data changes.

Pagination APIs