สร้างตารางแบ่งหน้า (Pagination) ใน Next.js ด้วย SWR

Aug. 14, 2024 · boychawin

วันนี้มาทำแบ่งหน้าตารางหรือ Pagination ซึ่งเป็นสิ่งสำคัญในระบบที่มีข้อมูลจำนวนมาก การทำให้ข้อมูลถูกโหลดและแสดงผลในแต่ละหน้าทำให้ผู้ใช้สามารถเรียกดูข้อมูลได้อย่างมีประสิทธิภาพและลดภาระการโหลดข้อมูลในคราวเดียว ในบทความนี้เราจะมาดูวิธีการสร้างตารางพร้อมฟังก์ชันการแบ่งหน้าโดยใช้ Next.js และ SWR

1. การใช้ SWR ในการดึงข้อมูล

ในตัวอย่างนี้ เราใช้ useSWR ซึ่งเป็น React Hook ที่ใช้ในการดึงข้อมูลจาก API และทำการจัดการสถานะการโหลด (loading) หรือการผิดพลาด (error) โดย SWR มีประสิทธิภาพในการจัดการกับข้อมูลที่เปลี่ยนแปลงบ่อยและรองรับการทำ caching อัตโนมัติ และเรามีบทความเกี่ยวกับ API เส้น /getProductList นี้ไว้ด้วย สร้าง API เพื่อทำ Pagination ด้วย NestJS และ Prisma

  const take = 10
  const [skip, setSkip] = React.useState(0)

const { data: repositories, isLoading, mutate } = useSWR(
  `localhost:4200/api/getProductList?skip=${skip}&take=${take}`,
  async (key) => await getData(key) // คือ การ fetch data ส่วนนี้ไม่มีโค้ดนะครับ
);

ในโค้ดนี้ repositories จะเก็บข้อมูลที่ถูกดึงมา, isLoading จะแสดงสถานะการโหลด, และ mutate ใช้สำหรับรีเฟรชข้อมูลที่ดึงมาโดยไม่ต้องโหลดหน้าทั้งหมดใหม่

2. การคำนวณจำนวนหน้าทั้งหมด

จากข้อมูลที่ถูกดึงมา เราสามารถคำนวณจำนวนหน้าทั้งหมดที่ต้องการได้โดยใช้ count และ take ซึ่งเป็นจำนวนข้อมูลที่เราต้องการแสดงต่อหน้า

const { count, data } = repositories || {}
const totalItems = count || 0;
const totalPages = Math.ceil(totalItems / take);

3. การสร้างฟังก์ชันสลับหน้า

ในการเปลี่ยนหน้า เราได้สร้างฟังก์ชัน switchPage ซึ่งใช้เพื่อปรับค่า skip ซึ่งเป็นตัวชี้ว่าต้องเริ่มดึงข้อมูลจากรายการที่เท่าไหร่


const switchPage = (newPageIndex) => {
  if (newPageIndex >= 1 && newPageIndex <= totalPages) {
    setSkip((newPageIndex - 1) * take);
  }
};

4. การสร้างตารางแสดงข้อมูล

ข้อมูลที่ถูกดึงมาจะถูกแสดงในรูปแบบตาราง โดยใช้ <table>


<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Stock</th>
    </tr>
  </thead>
  <tbody>
    {data?.map((item, i) => {
      return (
        <tr key={i}>
          <td>{item.name ?? '-'}</td>
          <td>{item.stock ?? "-"}</td>
        </tr>
      );
    })}
  </tbody>
</table>

5. การแสดงปุ่มสลับหน้า (Pagination)

เราทำการแสดงปุ่มสลับหน้าโดยใช้ button ซึ่งจะมีการไฮไลต์ปุ่มหน้าปัจจุบันด้วยสี #111 และสามารถคลิกเพื่อสลับหน้าได้


{totalPages > 1 && (
  <div>
      {Array.from({ length: totalPages }, (_, index) => (
        <button
          key={index}
          style={{color: (skip / take) + 1 === index + 1 ? '#111' : '#ccc'}}
          onClick={() => switchPage(index + 1)}
        >
          {index + 1}
        </button>
      ))}
  </div>
)}

สรุป

การสร้างตารางพร้อมฟังก์ชันแบ่งหน้าใน Next.js โดยใช้ SWR สามารถช่วยให้เราดึงข้อมูลได้อย่างมีประสิทธิภาพ โดยโครงสร้างของโค้ดนี้สามารถปรับแต่งเพิ่มเติมตามความต้องการของโปรเจกต์ได้ครับ