skip to Main Content

I have a table from @tanstack/react-table I want to implement pagination. I’ve the below so far and when I click next page it adds 1 to the pageIndex, but then immediately resets it back to 0.

CODE

"use client";

import { memo, useEffect, useMemo, useState } from "react";

import {
  flexRender,
  getCoreRowModel,
  getPaginationRowModel,
  useReactTable,
} from "@tanstack/react-table";

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";

import PaginationFooter from "./pagination-footer";

import { createClient } from "@/utils/supabase/client";

function DataTable({ columns }) {
  const [mounted, setMounted] = useState(false);
  const [data, setData] = useState([]);
  const [count, setCount] = useState(0);
  const [rowSelection, setRowSelection] = useState({});
  const [pagination, setPagination] = useState({
    pageIndex: 0,
    pageSize: 15,
  });

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    onRowSelectionChange: setRowSelection,
    pageCount: Math.ceil(count / pagination.pageSize),
    onPaginationChange: setPagination,
    getPaginationRowModel: getPaginationRowModel(),
    state: {
      rowSelection,
      pagination,
    },
  });

  const supabase = createClient();

  useEffect(() => {
    setMounted(true);
  }, []);

  useEffect(() => {
    async function fetchData() {
      const from = pagination.pageIndex * pagination.pageSize;
      const { data, count, error } = await supabase
        .from("contacts")
        .select("*", { count: "exact" })
        .order("created_at", { ascending: false })
        .range(from, from + pagination.pageSize - 1);

      if (error) {
        return;
      } else {
        setCount(count);
        setData(data);
      }
    }
    fetchData();
  }, [pagination.pageIndex]);

  useEffect(() => {
    const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
    console.log(selectedRows);
  }, [rowSelection]);

  if (!mounted) return null;

  return (
    <div className="h-full flex flex-col flex-1 overflow-x-auto">
      <div className="flex-grow overflow-x-auto min-h-0">
        {...table}
      </div>
      <div className="select-none bg-background">
        <PaginationFooter table={table} />
      </div>
    </div>
  );
}

export default memo(DataTable);

2

Answers


  1. Chosen as BEST ANSWER

    I had to add manualPagination for this to work.

    const table = useReactTable({
      data,
      columns,
      getCoreRowModel: getCoreRowModel(),
      onRowSelectionChange: setRowSelection,
      pageCount: Math.ceil(count / pagination.pageSize),
      onPaginationChange: setPagination,
      getPaginationRowModel: getPaginationRowModel(),
      manualPagination: true, // added
      state: {
        rowSelection,
        pagination,
      },
    });
    

  2. To manage pagination values in @tanstack/react-table u have to be Using Setter and Getters.

    so start with InitialState object with preferred value to start with it then use getters and setters for managing it through the code

    so your code will be like this for the pagination

    const { getState, setPageSize } = table;
    
    // Destructure pageIndex and pageSize from the table's state
    const { pageIndex, pageSize } = getState();
    
    // Handler function to update the page size
    const pageSizeHandler = (n: number) => {
      setPageSize(n);
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search