แสดงบทความที่มีป้ายกำกับ data table แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ data table แสดงบทความทั้งหมด

วันอังคารที่ 1 เมษายน พ.ศ. 2568

การแสดงผลตารางใน Next.js ด้วย TanStack Table: ง่าย สวย และยืดหยุ่นสุดๆ

ถ้าคุณเคยต้องทำตารางใน React หรือ Next.js แล้วรู้สึกว่ามันยุ่งยากไปหมด ไม่ว่าจะเป็นการจัดการข้อมูล การกรอง (filtering) การเรียงลำดับ (sorting) หรือการแบ่งหน้า (pagination) วันนี้เราจะมาแนะนำ TanStack Table (หรือชื่อเดิมคือ React Table) ที่จะช่วยให้คุณสร้างตารางขั้นเทพได้แบบง่ายๆ

ทำไมต้องใช้ TanStack Table?

ในโปรเจกต์ที่ต้องแสดงข้อมูลในรูปแบบตาราง เช่น รายการคำสั่งซื้อ, รายการผู้ใช้ หรือข้อมูลสถิติต่างๆ เราต้องการฟีเจอร์พวกนี้:

✅ การจัดการข้อมูลที่ยืดหยุ่น (เช่น ใช้ API ดึงข้อมูลมาแสดง)
✅ Sorting, Filtering, และ Pagination แบบไม่ต้องเขียนเอง
✅ รองรับการใช้งานกับ Next.js และ SSR (Server-side Rendering)

TanStack Table ทำได้หมด! 🎉

ติดตั้ง TanStack Table

ก่อนอื่น เราต้องติดตั้งไลบรารีก่อน

npm install @tanstack/react-table

หรือถ้าใช้ Yarn

yarn add @tanstack/react-table


ตัวอย่างการใช้งานพื้นฐาน

มาลองสร้างตารางง่ายๆ กันก่อน โดยใช้ข้อมูลแบบ static

1. ตั้งค่าข้อมูลและคอลัมน์

const data = [
  { id: 1, name: 'John Doe', age: 28, email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', age: 32, email: 'jane@example.com' },
  { id: 3, name: 'Bob Brown', age: 24, email: 'bob@example.com' },
];

const columns = [
  { accessorKey: 'id', header: 'ID' },
  { accessorKey: 'name', header: 'ชื่อ' },
  { accessorKey: 'age', header: 'อายุ' },
  { accessorKey: 'email', header: 'อีเมล' },
];

อธิบาย:

  • data คือข้อมูลที่เราจะเอามาแสดง
  • columns กำหนดโครงสร้างของตาราง ใช้ accessorKey เพื่อระบุคีย์ของข้อมูล


2. ใช้ TanStack Table เพื่อแสดงตาราง

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

export default function MyTable() {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <table border="1">
      <thead>
        {table.getHeaderGroups().map((headerGroup) => (
          <tr key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <th key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody>
        {table.getRowModel().rows.map((row) => (
          <tr key={row.id}>
            {row.getVisibleCells().map((cell) => (
              <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

สรุปโค้ด:

  • useReactTable() ใช้สร้างตารางจาก data และ columns
  • getCoreRowModel() ใช้เพื่อจัดการโครงสร้างของข้อมูล
  • flexRender() ช่วยให้เราสามารถเรนเดอร์ค่าที่กำหนดใน columns ได้


เพิ่ม Sorting (เรียงลำดับ)

ถ้าอยากให้ตารางสามารถเรียงลำดับ (sorting) ได้ ให้เพิ่ม getSortedRowModel()

import { useReactTable, getCoreRowModel, getSortedRowModel, flexRender } from '@tanstack/react-table';

export default function MyTable() {
  const [sorting, setSorting] = React.useState([]);
 
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    onSortingChange: setSorting,
    state: { sorting },
  });

  return (
    <table border="1">
      <thead>
        {table.getHeaderGroups().map((headerGroup) => (
          <tr key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <th key={header.id} onClick={() => header.column.getToggleSortingHandler()?.()}>
                {flexRender(header.column.columnDef.header, header.getContext())}
                {header.column.getIsSorted() === 'asc' ? ' 🔼' : header.column.getIsSorted() === 'desc' ? ' 🔽' : ''}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody>
        {table.getRowModel().rows.map((row) => (
          <tr key={row.id}>
            {row.getVisibleCells().map((cell) => (
              <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

ตอนนี้เราสามารถคลิกที่หัวตารางเพื่อเรียงข้อมูลได้แล้ว! 🎉


เพิ่ม Pagination (แบ่งหน้า)

ถ้าข้อมูลเยอะๆ เราอาจต้องการ pagination เพื่อให้ผู้ใช้สามารถเลื่อนดูหน้าอื่นๆ ได้

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

export default function MyTable() {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
  });

  return (
    <div>
      <table border="1">
        <thead>
          {table.getHeaderGroups().map((headerGroup) => (
            <tr key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <th key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {table.getRowModel().rows.map((row) => (
            <tr key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
      <div>
        <button onClick={() => table.previousPage()} disabled={!table.getCanPreviousPage()}>
          ก่อนหน้า
        </button>
        <span> หน้า {table.getState().pagination.pageIndex + 1} </span>
        <button onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
          ถัดไป
        </button>
      </div>
    </div>
  );
}


สรุป

✅ TanStack Table ช่วยให้สร้างตารางใน Next.js ได้ง่ายและยืดหยุ่น
✅ รองรับ Sorting, Pagination, Filtering
✅ ทำงานได้ดีทั้ง Client-side และ Server-side Rendering

ถ้าคุณต้องการตารางที่เร็วและยืดหยุ่น TanStack Table คือตัวเลือกที่ดีสุด! 

การใช้ Image Optimization ใน Next.js: โหลดไว SEO ดี ประหยัดแบนด์วิธ!

เคยเจอปัญหาเว็บโหลดช้าเพราะรูปภาพขนาดใหญ่หรือเปล่า? 📷 ถ้าใช่ Next.js มีฟีเจอร์ Image Optimization ที่ช่วยให้รูปภาพโหลดเร็วขึ้น อัตโนมัติ ไม...