React-Table: usePagination

Contents

usePagination

Adding pagination to the table is relatively easy as well. We just have to pass a couple of settings in the initial state prop.

Then we add the pagination hook to the datatable, and that allows us to get a bunch of new table props that we add to some page controls.

The big change is that instead of rendering the rows prop, we will now render the pages prop. Which is very similar to rows, it just a specific subsection, depending on what page we are on, how many items per page etc.

Let’s take a look at the working result first.

Edit react-table_usePagination

initialState

There are a lot of initialState options when you are using pagination, but only two of them are required. pageSize and pageIndex.

/components/PeopleDataTable.js
import React, { Component } from "react";

// components
import Datatable from "./DataTable";
import Loading from "./Loading";

// utilities
import makeData from "../utilities/makeData";

const data = makeData(200);

const columns = [
  {
    Header: "First Name",
    accessor: "firstName"
  },
  // ...
];

const initialState = {
  pageSize: 10,  pageIndex: 0};

class PeopleDataTable extends Component {
  // Loading must be handled here because DataTable MUST have data on load
  renderTable() {
    if (!data) {
      return <Loading />;
    } else {
      return (
        <Datatable data={data} columns={columns} initialState={initialState} />
      );
    }
  }

  render() {
    return <>{this.renderTable()}</>;
  }
}

export default PeopleDataTable;

new props

After we add the usePagination hook, we will have access to many new props that we can then use in the render section.

Take note that we are replacing row.map with page.map which is just a sub-selection of all rows.

/components/DataTable.js
import React from "react";
import { useTable, usePagination } from "react-table";
const DataTable = (props) => {
  // Memos
  const data = React.useMemo(() => props.data, [props.data]);
  const columns = React.useMemo(() => props.columns, [props.columns]);
  const initialState = React.useMemo(() => props.initialState);

  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    prepareRow,
    page,    canPreviousPage,    canNextPage,    pageOptions,    pageCount,    gotoPage,    nextPage,    previousPage,    setPageSize,    state: { pageIndex, pageSize }  } = useTable(
    {
      columns,
      data,
      initialState
    },
    usePagination  );
  //change
  return (
    <>
      <table {...getTableProps()}>
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th {...column.getHeaderProps()}>{column.render("Header")}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {page.map((row, i) => {            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map((cell) => {
                  return (
                    <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <div className="pagination">        <button onClick={() => gotoPage(0)} disabled={!canPreviousPage}>          {"<<"}        </button>{" "}        <button onClick={() => previousPage()} disabled={!canPreviousPage}>          {"<"}        </button>{" "}        <button onClick={() => nextPage()} disabled={!canNextPage}>          {">"}        </button>{" "}        <button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>          {">>"}        </button>{" "}        <span>          Page{" "}          <strong>            {pageIndex + 1} of {pageOptions.length}          </strong>{" "}        </span>        <span>          | Go to page:{" "}          <input            type="number"            defaultValue={pageIndex + 1}            onChange={(e) => {              const page = e.target.value ? Number(e.target.value) - 1 : 0;              gotoPage(page);            }}            style={{ width: "100px" }}          />        </span>{" "}        <select          value={pageSize}          onChange={(e) => {            setPageSize(Number(e.target.value));          }}        >          {[10, 20, 30, 40, 50].map((pageSize) => (            <option key={pageSize} value={pageSize}>              Show {pageSize}            </option>          ))}        </select>      </div>    </>
  );
};

export default DataTable;

You can change the pagination controls however you like, this is just a simple demonstration on how to consume the props that usePagination provides.