I am trying to create a reusable shadcn table which i can use to render data gotten from an API. The API handles the pagination and sends back something like this with the response data:
"next_page_url": "REDACTED/payments?page=2",
"path": "REDACTED/payments",
"per_page": 15,
"prev_page_url": null,
"to": 15,
"total": 31
I tried using the Shadcn Data Table but ended up with a table with broken/not functioning pagination due to the length of data being passed to it.
<div className='flex flex-wrap items-center gap-4'>
<DataTableSearch
searchKey='name'
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
setPage={setPage}
/>
<DataTableFilterBox
filterKey='role'
title='Role'
options={ROLE_OPTIONS}
setFilterValue={setRoleFilter}
filterValue={roleFilter}
/>
<DataTableResetFilter
isFilterActive={isAnyFilterActive}
onReset={resetFilters}
/>
</div>
<DataTable columns={columns} data={data} totalItems={totalData} />
</div>
Shadcn Datatable works for client-side pagination for smaller data chunks, I suggest you use the shadcn regular table, and a pagination component to manage the page count and next and prev
See a basic example in Nextjs
"use client";
import { Button } from "@/components/ui/button";
import { useRouter, useSearchParams } from "next/navigation";
interface PaginationProps {
currentPage: number;
lastPage: number;
}
export function Pagination({ currentPage, lastPage }: PaginationProps) {
const router = useRouter();
const searchParams = useSearchParams();
const handlePageChange = (page: number) => {
const params = new URLSearchParams(searchParams.toString());
params.set("page", page.toString());
router.push(`?${params.toString()}`);
};
return (
<div className="flex items-center justify-end space-x-2 py-4">
<div className="text-sm text-muted-foreground">
Page {currentPage} of {lastPage}
</div>
<div className="space-x-2">
<Button
variant="outline"
size="sm"
disabled={currentPage === 1}
onClick={() => handlePageChange(currentPage - 1)}
>
Previous
</Button>
<Button
variant="outline"
size="sm"
disabled={currentPage === lastPage}
onClick={() => handlePageChange(currentPage + 1)}
>
Next
</Button>
</div>
</div>
);
}
This allows you to change the page in the URL and in the parent component you can use this to update the page and fetch the new page data.
I hope this helps!