- Published on
How to create a pagination using prisma, Next.js and shadcn/ui Data Table?
- Authors
- Name
- Ripal & Zalak
How to create a pagination using prisma, Next.js and shadcn/ui Data Table?
Efficiently managing large datasets requires implementing pagination. This guide demonstrates how to set up server-side pagination for a Shadcn Data Table using Prisma, Next.js, and Zustand for state management.
Overview
Pagination ensures only a subset of data is loaded at a time, improving performance and user experience. Using Prisma’s skip
and take
methods with a Shadcn Data Table, we can implement clean and efficient pagination.
Step-by-Step Implementation
Step 1: Set Up Zustand for Pagination State
Zustand is used to manage pagination state across components.
import { create } from "zustand";
interface ProductPaginationState {
page: number;
perPage: number;
setPage: (page: number) => void;
setPerPage: (perPage: number) => void;
}
export const useProductPagination = create<ProductPaginationState>((set) => ({
page: 1,
perPage: 10,
setPage: (page) => set({ page }),
setPerPage: (perPage) => set({ perPage }),
}));
Step 2: Fetch Paginated Data with Prisma
Modify your data-fetching function to include pagination parameters.
import prismadb from '@/lib/prismadb'
import { useProductPagination } from '@/lib/store/product-pagination'
export async function getPaginatedData() {
const { page, perPage } = useProductPagination.getState()
const skip = (page - 1) * perPage
const products = await prismadb.product.findMany({
skip,
take: perPage,
})
const totalProducts = await prismadb.product.count()
return {
products: products.map((product, index) => ({
id: index + 1 + skip,
name: product.name,
description: product.description,
category: product.category,
origin: product.origin,
sell: product.sellingPrice,
purchase: product.purchasedPrice,
status: product.status === 'active' ? 'Active' : 'Inactive',
})),
total: totalProducts,
}
}
Step 3: Update the Data Table Component
Integrate pagination controls into the Data Table component.
import { DataTable } from '@/components/ui/data-table'
import { useProductPagination } from '@/lib/store/product-pagination'
import { getPaginatedData } from '@/lib/api'
import { useEffect, useState } from 'react'
export default function PaginatedTable() {
const [data, setData] = useState([])
const [total, setTotal] = useState(0)
const { page, perPage, setPage, setPerPage } = useProductPagination()
useEffect(() => {
async function fetchData() {
const { products, total } = await getPaginatedData()
setData(products)
setTotal(total)
}
fetchData()
}, [page, perPage])
return (
<div>
<DataTable data={data} columns={columns} />
<div className="mt-4 flex items-center justify-between">
<button
onClick={() => setPage(page - 1)}
disabled={page === 1}
className="rounded bg-gray-200 px-4 py-2"
>
Previous
</button>
<span>
Page {page} of {Math.ceil(total / perPage)}
</span>
<button
onClick={() => setPage(page + 1)}
disabled={page * perPage >= total}
className="rounded bg-gray-200 px-4 py-2"
>
Next
</button>
</div>
</div>
)
}
Step 4: Add Pagination Controls
Ensure pagination controls update page
and perPage
in the Zustand store.
<button onClick={() => setPerPage(20)} className="rounded bg-gray-200 px-4 py-2">
Show 20 Per Page
</button>
FAQs
Why use Zustand instead of React state?
Zustand provides a simple, scalable solution for managing state across multiple components without prop drilling.
Can I implement infinite scrolling instead of pagination?
Yes, you can use Prisma’s skip
and take
methods to load more data incrementally, replacing pagination controls with a "Load More" button.
How do I handle large datasets efficiently?
Use database indexes and only fetch the fields necessary for the table to reduce query complexity.
Conclusion
With Prisma, Next.js, and Shadcn’s Data Table, implementing server-side pagination is straightforward and efficient. By combining these tools with Zustand, you can manage state seamlessly and ensure optimal performance for large datasets.