การนำ TabulatorPlus ไปใช้ใน React ให้มีประสิทธิภาพสูงสุด จำเป็นต้องจัดการเรื่อง Lifecycle ของ Component ให้ดีครับ โดยเฉพาะการป้องกันไม่ให้เกิดการสร้าง Instance ซ้อนกันหลายตัว ซึ่งมักพบใน React 18+
นี่คือตัวอย่างโค้ดที่ครอบคลุมการจัดการ Instance, การ Refresh ข้อมูล และการ Unmount อย่างสะอาดครับ
ตัวอย่าง React Component: UserTable
import { useEffect, useRef } from 'react';
import TabulatorPlus from './TabulatorPlus';
// อย่าลืม import CSS ของ tabulator ในโปรเจกต์ด้วย
import "tabulator-tables/dist/css/tabulator.min.css"; function UserTable ({ data }) { const tableRef = useRef (null) ; // อ้างอิง DOM Element const tabulatorInstance = useRef (null) ; // เก็บ Instance ไว้เพื่อเรียกใช้ Method อื่น ๆ (Reused Instance) // 1. Hook สำหรับการ Initialize และ Cleanup (Unmount) useEffect ( () => { if (tableRef.current && !tabulatorInstance.current) { // สร้าง Instance ครั้งแรก tabulatorInstance.current = new TabulatorPlus (tableRef.current, { data: data, // ข้อมูลเริ่มต้น columns: [ { title: "Name", field: "name", width: 150 }, { title: "Age", field: "age", hozAlign: "left" }, { title: "Status", field: "status", formatter: "tickCross" }, ], }, "user-table-storage") ; } // Cleanup: ล้างข้อมูลและทำลาย Instance เมื่อ Unmount return () => { if (tabulatorInstance.current) { console.log ("Cleaning up Tabulator instance...") ; tabulatorInstance.current.destroy () ; tabulatorInstance.current = null; } }; }, []) ; // ทำงานครั้งเดียวตอน Mount // 2. Hook สำหรับการ Refresh ข้อมูล (เมื่อ Props 'data' เปลี่ยนแปลง) useEffect ( () => { if (tabulatorInstance.current) { console.log ("Refreshing data...") ; // ใช้ setData เพื่ออัปเดตข้อมูลโดยไม่สร้างตารางใหม่ (Performance ดีกว่า) tabulatorInstance.current.setData (data) ; } }, [data]) ; // 3. ฟังก์ชันสำหรับเรียกใช้งาน Instance จากภายนอก (Manual Refresh/Action) const handleManualRefresh = () => { if (tabulatorInstance.current) { // เช่น สั่งให้ตารางวาดใหม่หลังเปลี่ยนขนาดหน้าจอ หรือล้าง Filter tabulatorInstance.current.clearFilter (true) ; tabulatorInstance.current.redraw (true) ; } }; return ;
} export default UserTable;
คำอธิบายจุดสำคัญ
tabulatorInstance.current: เราใช้useRefเก็บตัวแปร Instance ไว้แทนuseStateเพราะเราไม่ต้องการให้ React ทำการ re-render ทุกครั้งที่ตัวแปรนี้เปลี่ยนค่า แต่เรายังต้องการอ้างอิงถึงมันเพื่อใช้ Method อย่าง.setData ()หรือ.redraw ()- การล้างข้อมูล : ใน
returnของuseEffectชุดแรก เราสั่งtable.destroy ()เพื่อให้ Tabulator ถอน Event Listeners และล้าง DOM ที่สร้างขึ้นทิ้ง ป้องกันปัญหา Memory Leak และอาการตารางซ้อนกัน - การ Refresh : แทนที่จะสร้าง
new TabulatorPlusใหม่ทุกครั้งที่ข้อมูลเปลี่ยน เราใช้useEffectตัวที่สองมาดักจับการเปลี่ยนแปลงของdataแล้วใช้.setData ()ซึ่งเป็นวิธีที่ Tabulator แนะนำครับ - Handling Strict Mode: การเช็ค
if (!tabulatorInstance.current)ช่วยป้องกันไม่ให้ React สร้างตาราง 2 รอบในโหมด Development