Published on

How to create a pagination using prisma, Next.js and shadcn/ui Data Table?

Authors
  • Name
    Ripal & Zalak
    Twitter

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.