ทำความรู้จัก TanStack Query และทำไมต้องใช้ TypeScript
ถ้าคุณเคยเขียนแอปที่ต้องดึงข้อมูลจากเน็ต คุณคงรู้ว่ามันวุ่นวายแค่ไหน ทั้งเรื่องการรอข้อมูล (Loading) การจัดการข้อผิดพลาด (Error) และการเก็บข้อมูลไว้ใช้ซ้ำ TanStack Query (เครื่องมือจัดการสถานะข้อมูลจากเซิร์ฟเวอร์) เข้ามาแก้ปัญหานี้ให้เราจัดการงานเหล่านี้ได้ง่ายขึ้น
ลองนึกภาพว่าคุณสั่งอาหารผ่านแอป ถ้าแอปไม่บอกว่าอาหารกำลังทำอยู่ หรือบอกไม่ได้ว่าร้านปิด คุณคงหงุดหงิด TanStack Query เปรียบเสมือนพนักงานเสิร์ฟที่คอยแจ้งสถานะให้คุณรู้ตลอดเวลาว่า ข้อมูลกำลังโหลด หรือมีปัญหาอะไรเกิดขึ้นไหม
เมื่อใช้ร่วมกับ TypeScript (ภาษาที่ช่วยตรวจสอบความถูกต้องของข้อมูล) เราจะรู้ทันทีว่าข้อมูลที่ได้มามีหน้าตาเป็นอย่างไร ทำให้เขียนโค้ดได้มั่นใจขึ้นมาก ลดบั๊ก (จุดผิดพลาดในโปรแกรม) ที่เกิดจากการเดาโครงสร้างข้อมูลไปได้เยอะเลยครับ
เตรียมโปรเจกต์ให้พร้อมใช้งาน
ก่อนเริ่มเขียนโค้ด เราต้องติดตั้งไลบรารี (ชุดคำสั่งที่คนอื่นเขียนไว้ให้เราใช้) ที่จำเป็นก่อน ให้เปิด Terminal (ช่องสำหรับพิมพ์คำสั่งคอมพิวเตอร์) ในโปรเจกต์ของคุณ แล้วพิมพ์คำสั่งตามนี้ได้เลย
npm install @tanstack/react-query
# ติดตั้งไลบรารีหลักสำหรับจัดการข้อมูล
npm install --save-dev @types/react
# ติดตั้งตัวช่วยตรวจสอบชนิดข้อมูลสำหรับ React
หลังจากติดตั้งเสร็จ คุณต้องไปที่ไฟล์หลักของแอป เช่น main.tsx เพื่อครอบแอปด้วย QueryClientProvider (ตัวจ่ายข้อมูลให้ส่วนต่างๆ ในแอป) เพื่อให้ทุกส่วนในแอปเรียกใช้ TanStack Query ได้
จุดที่มือใหม่มักพลาดคือลืมครอบ Provider ทำให้เรียกใช้คำสั่งแล้วพังทันที อย่าลืมเช็คให้แน่ใจว่าเราได้ห่อหุ้มส่วนประกอบ (Component) ที่จะเรียกใช้ข้อมูลไว้ข้างในเรียบร้อยแล้วนะครับ
การใช้ useQuery เพื่อดึงข้อมูลอย่างปลอดภัย
useQuery (คำสั่งสำหรับดึงข้อมูล) คือหัวใจหลักที่เราใช้ดึงข้อมูลจาก API (ช่องทางเชื่อมต่อข้อมูลระหว่างแอปกับเซิร์ฟเวอร์) การใส่ TypeScript เข้าไปจะช่วยให้เรากำหนดได้ว่า ข้อมูลที่ได้มาควรเป็นแบบไหน
type User = { id: number; name: string };
const { data, isLoading, error } = useQuery<User, Error>({
queryKey: ['user'], // ชื่อเรียกเฉพาะของข้อมูลชุดนี้
queryFn: () => fetch('/api/user').then(res => res.json()), // ฟังก์ชันดึงข้อมูลจริง
});
ในตัวอย่างเรากำหนด <User, Error> เพื่อบอกว่า data จะมีหน้าตาเป็น User และถ้ามีปัญหา error จะเป็นชนิด Error ทำให้เวลาเราพิมพ์ data. โปรแกรมจะแนะนำชื่อฟิลด์ (ช่องเก็บข้อมูลย่อย) ให้เราทันที
ถ้าเราไม่ได้กำหนดแบบนี้ TypeScript จะเดาว่าเป็น unknown (ไม่รู้ชนิด) ทำให้เขียนโค้ดต่อลำบาก การระบุชนิดข้อมูลตั้งแต่ต้นจึงเป็นนิสัยที่ดีของโปรแกรมเมอร์มืออาชีพครับ
การใช้ useMutation เพื่อส่งข้อมูลไปเซิร์ฟเวอร์
ถ้า useQuery คือการดึงข้อมูล useMutation (คำสั่งสำหรับแก้ไขหรือส่งข้อมูล) ก็คือการส่งคำสั่งไปเปลี่ยนข้อมูล เช่น การกดปุ่มบันทึก หรือการลบข้อมูลในระบบ
const mutation = useMutation<void, Error, string>({
mutationFn: (newName: string) =>
fetch('/api/user', { method: 'POST', body: JSON.stringify({ name: newName }) }),
});
สังเกตว่าเราใส่ <void, Error, string> ลงไป ตัวแรกคือผลลัพธ์ที่จะได้ ตัวที่สองคือ Error และตัวที่สามคือชนิดข้อมูลที่เราส่งเข้าไปในฟังก์ชัน (ในที่นี้คือชื่อที่เป็นข้อความ)
การทำแบบนี้ช่วยป้องกันไม่ให้เราส่งข้อมูลผิดประเภทเข้าไปในเซิร์ฟเวอร์ เช่น ถ้าเราต้องส่งตัวเลขแต่เผลอส่งข้อความไป ตัวโปรแกรมจะเตือนเราทันทีตั้งแต่ตอนเขียนโค้ด ทำให้ไม่ต้องไปเสียเวลาแก้บั๊กตอนรันแอปจริง
ข้อควรระวังและเทคนิคจัดการ Error
เวลาเขียนโปรแกรมจริง ข้อมูลอาจไม่มาตามนัดเสมอไป การจัดการ Error (ข้อผิดพลาด) จึงสำคัญมาก อย่าปล่อยให้แอปค้างหน้าจอขาวเวลาดึงข้อมูลไม่ได้เด็ดขาด
ใช้ตัวแปร isError หรือ error ที่ได้จาก useQuery มาเช็คเงื่อนไขเพื่อแสดงข้อความเตือนผู้ใช้ เช่น "ขออภัย เกิดข้อผิดพลาด กรุณาลองใหม่" แทนที่จะปล่อยให้แอปพัง (Crash)
ข้อควรระวัง: อย่าลืมเช็คชนิดข้อมูลของ error ให้ดี เพราะบางครั้งมันอาจไม่ใช่ Error ที่เราคาดไว้ ให้ใช้การตรวจสอบแบบ if (error instanceof Error) เพื่อความปลอดภัยสูงสุดก่อนนำไปแสดงผลครับ
สรุป: การนำไปใช้จริงในโปรเจกต์ของคุณ
การใช้ TanStack Query คู่กับ TypeScript ไม่ใช่แค่เรื่องของความสวยงาม แต่เป็นเรื่องของความปลอดภัยและการทำงานที่รวดเร็วขึ้น ในโปรเจกต์จริง คุณควรสร้างไฟล์แยกสำหรับเก็บคำสั่งดึงข้อมูลไว้ต่างหาก
ตัวอย่างเช่น คุณอาจสร้างไฟล์ api.ts ไว้รวมคำสั่ง useQuery ทั้งหมด เพื่อให้เรียกใช้ง่ายและจัดการแก้ไขในที่เดียว หาก API เปลี่ยนโครงสร้าง คุณก็แค่แก้ที่จุดเดียว ไม่ต้องตามไล่แก้ทุกหน้าในแอป
การฝึกใช้ TypeScript ให้ชินตั้งแต่ตอนนี้จะทำให้คุณทำงานร่วมกับทีมได้ง่ายขึ้น เพราะโค้ดของคุณจะมีระเบียบและอ่านง่าย ไม่ว่าใครมาอ่านต่อก็เข้าใจได้ทันที เริ่มฝึกจากโปรเจกต์เล็กๆ แล้วขยับขยายไปเรื่อยๆ นะครับ