😎 React TypeScript

เทคนิคเขียน React ด้วย TypeScript: ทำ Generic Components และเพิ่ม Performance ให้แอปลื่นไหล

7 นาที 17 views บันทึกเป็น PDF
เทคนิคเขียน React ด้วย TypeScript: ทำ Generic Components และเพิ่ม Performance ให้แอปลื่นไหล

เรียนรู้วิธีเขียน Generic Components เพื่อลดการเขียนโค้ดซ้ำ และเทคนิคใช้ useMemo กับ useCallback เพื่อเพิ่มความเร็วให้แอป React ของคุณทำงานได้ลื่นไหลไม่มีสะดุด

ทำไมต้องรู้จัก Generic Components และการทำ Performance

เวลาเราเขียนโปรแกรม เรามักจะเจอปัญหาว่าต้องเขียนโค้ดซ้ำๆ เพื่อจัดการข้อมูลที่หน้าตาคล้ายกัน Generic Components (คอมโพเนนต์ที่รองรับข้อมูลได้หลายประเภท) คือทางแก้ที่ช่วยให้เราเขียนโค้ดครั้งเดียวแต่ใช้ได้กับทุกงาน เปรียบเหมือนกล่องอเนกประสงค์ที่ใส่ของได้ทุกอย่าง ไม่ว่าจะเป็นหนังสือ เสื้อผ้า หรืออุปกรณ์ไฟฟ้า

การเขียนโปรแกรมให้ Performance (ความเร็วและประสิทธิภาพของแอป) ดีขึ้นก็สำคัญไม่แพ้กัน ถ้าเราปล่อยให้คอมโพเนนต์คำนวณงานหนักทุกครั้งที่หน้าจอขยับ แอปก็จะช้าและกระตุก การเลือกใช้เครื่องมืออย่าง useMemo (คำสั่งจำผลลัพธ์การคำนวณ) และ useCallback (คำสั่งจำฟังก์ชันเพื่อไม่ให้สร้างใหม่) จะช่วยให้แอปเราลื่นไหลเหมือนรถที่เปลี่ยนน้ำมันเครื่องใหม่ตลอดเวลา

มือใหม่หลายคนมักมองข้ามเรื่องนี้เพราะแอปยังมีขนาดเล็ก แต่ถ้าฝึกไว้ตั้งแต่ตอนนี้ จะช่วยให้เราเขียนโค้ดที่ Scale (ขยายขนาดรองรับผู้ใช้ได้มากขึ้น) ได้ง่ายในอนาคต การเข้าใจเรื่อง Type Definition (การกำหนดชนิดข้อมูลให้ชัดเจน) จะช่วยให้เราหาบั๊ก (ข้อผิดพลาดของโปรแกรม) ได้เร็วกว่าเดิมมาก เพราะโปรแกรมจะเตือนเราทันทีถ้าใส่ข้อมูลผิดประเภท

สร้าง Generic Components แบบมือโปร

ลองจินตนาการว่าเราต้องทำรายการแสดงรายชื่อคน และรายการแสดงรายชื่อสินค้า ถ้าเราเขียนคอมโพเนนต์แยกกัน เราก็ต้องนั่งแก้โค้ดสองที่เสมอเมื่อต้องการเปลี่ยนดีไซน์ แต่ถ้าเราใช้ Generics (การสร้างโครงสร้างโค้ดที่ยืดหยุ่น) เราจะทำคอมโพเนนต์เดียวที่รับข้อมูลอะไรก็ได้เข้ามาแสดงผล

เราจะใช้สัญลักษณ์ <T> เพื่อบอกว่า T คือตัวแทนของชนิดข้อมูลที่จะส่งเข้ามาในภายหลัง วิธีนี้ทำให้เราได้ประโยชน์จาก Type Safety (ความปลอดภัยในการกำหนดชนิดข้อมูล) คือถ้าเราส่งข้อมูลผิดประเภทไป คอมไพเลอร์ (ตัวตรวจสอบโค้ดก่อนรัน) จะฟ้องทันที ทำให้เราไม่ต้องเดาว่าข้อมูลข้างในคืออะไร

นี่คือตัวอย่างการเขียน List ที่รับข้อมูลแบบ Generic เข้ามา:

// รายการที่รองรับข้อมูลทุกชนิด
interface ListProps<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
}

export const List = <T,>({ items, renderItem }: ListProps<T>) => {
  return <ul>{items.map((item, index) => renderItem(item))}</ul>;
};

โค้ดด้านบนสร้างตัวแปร List ที่ยอมรับข้อมูล items แบบใดก็ได้ โดยมีเงื่อนไขว่าต้องบอกวิธีแสดงผลผ่าน renderItem ข้อดีคือเราสามารถนำไปใช้กับหน้าจอโปรไฟล์หรือหน้าตะกร้าสินค้าได้ทันทีโดยไม่ต้องเขียนโค้ดใหม่

เพิ่มความเร็วด้วย useMemo

บางครั้งเราต้องคำนวณข้อมูลชุดใหญ่ เช่น การเรียงลำดับรายชื่อผู้ใช้งาน 1,000 คน ถ้าเราไม่ใช้ useMemo (คำสั่งจำผลลัพธ์) ทุกครั้งที่คอมโพเนนต์มีการอัปเดต คอมพิวเตอร์จะคำนวณใหม่ทั้งหมดทันที ซึ่งเสียเวลาและทำให้หน้าจอค้างได้

การใช้ useMemo<T> ช่วยให้เราบอก React ว่า "เก็บผลลัพธ์นี้ไว้นะ ถ้าข้อมูลต้นทางไม่เปลี่ยน ไม่ต้องคำนวณใหม่" เปรียบเหมือนการจดสูตรคูณไว้ในกระดาษ ถ้ามีคนถามเลขเดิม เราก็แค่หยิบกระดาษขึ้นมาดู ไม่ต้องเสียเวลาคิดเลขใหม่ในหัวอีกรอบ

ลองดูตัวอย่างการใช้งานเพื่อประหยัดพลังงานคอมพิวเตอร์:

// ใช้ useMemo เก็บผลลัพธ์ที่คำนวณแล้ว
const sortedItems = useMemo<User[]>(() => {
  return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]); // คำนวณใหม่เฉพาะเมื่อ items เปลี่ยนเท่านั้น

ในตัวอย่างนี้ sortedItems จะไม่ถูกเรียงลำดับใหม่หากเราไม่ได้เปลี่ยนข้อมูลใน items วิธีนี้ช่วยให้แอปตอบสนองไวขึ้นมาก โดยเฉพาะในโปรเจกต์ที่มีการแสดงผลข้อมูลจำนวนมากในหน้าเดียว

จัดการฟังก์ชันด้วย useCallback

ปัญหาที่พบบ่อยใน React คือฟังก์ชันถูกสร้างใหม่ทุกครั้งที่คอมโพเนนต์รัน ซึ่งทำให้คอมโพเนนต์ลูกเข้าใจผิดว่าฟังก์ชันเปลี่ยนไปแล้ว จึงต้องวาดหน้าจอใหม่โดยไม่จำเป็น การใช้ useCallback (คำสั่งจำฟังก์ชัน) จึงเข้ามาช่วยแก้ปัญหานี้

เมื่อเราใช้ useCallback เราจะได้ฟังก์ชันเดิมกลับมาเสมอ ตราบใดที่ค่าที่ต้องใช้ในฟังก์ชันนั้นยังเหมือนเดิม มันช่วยลดภาระการทำงานของเบราว์เซอร์ได้มหาศาล มือใหม่มักพลาดด้วยการใส่ทุกอย่างใน Dependency Array (รายการตัวแปรที่คอยเฝ้าระวัง) จนทำให้มันทำงานบ่อยเกินไป

มาดูวิธีเขียนที่ถูกต้องเพื่อไม่ให้ฟังก์ชันถูกสร้างใหม่พร่ำเพรื่อ:

// จำฟังก์ชันคลิกไว้ไม่ให้สร้างใหม่
const handleClick = useCallback((id: number) => {
  console.log("คลิกที่ไอดี:", id);
}, []); // ใส่ค่าว่างเพื่อให้ฟังก์ชันนี้คงที่ตลอดไป

การใช้ useCallback คู่กับ memo (เครื่องมือช่วยหยุดการวาดหน้าจอซ้ำ) จะทำให้คอมโพเนนต์ของคุณทำงานได้อย่างมีประสิทธิภาพสูงสุด จุดที่ต้องระวังคืออย่าใช้กับทุกฟังก์ชัน เพราะการจำฟังก์ชันก็กินหน่วยความจำเหมือนกัน ให้ใช้เฉพาะกับฟังก์ชันที่ส่งต่อให้คอมโพเนนต์ลูกเท่านั้น

จุดที่มือใหม่มักพลาดและวิธีแก้ไข

ข้อผิดพลาดอันดับหนึ่งคือการกำหนด Type เป็น any (ชนิดข้อมูลอะไรก็ได้) เพราะขี้เกียจพิมพ์ การทำแบบนี้จะทำให้ TypeScript (เครื่องมือช่วยเช็คชนิดข้อมูล) กลายเป็นไร้ความหมายทันที เหมือนเรามีเข็มทิศแต่ไม่ยอมมองมันก่อนเดินเข้าป่า

อีกจุดคือการลืมใส่ Dependency ให้ครบใน useMemo หรือ useCallback ซึ่งจะทำให้ข้อมูลที่แสดงผลเก่ากว่าความจริง ทำให้ผู้ใช้สับสนว่าทำไมกดปุ่มแล้วค่าไม่เปลี่ยน วิธีแก้คือใช้ ESLint (เครื่องมือช่วยตรวจหาจุดผิดในโค้ด) ที่จะคอยเตือนเราเสมอถ้าเราลืมใส่ค่าที่ต้องเฝ้าระวัง

สุดท้ายคือการใช้ Generics ซับซ้อนเกินจำเป็นจนอ่านโค้ดไม่รู้เรื่อง ถ้าคุณมีคอมโพเนนต์ที่ต้องรับข้อมูลแค่ชนิดเดียว ไม่จำเป็นต้องทำเป็น <T> ให้ปวดหัว เขียนให้ง่ายและตรงไปตรงมาคือหัวใจของโปรแกรมเมอร์ที่เก่งครับ

สรุป: การนำไปใช้จริงในงานเขียนโค้ด

การทำ Generic Components ช่วยให้คุณลดการเขียนโค้ดซ้ำซ้อนได้ดีมาก และการใช้ useMemo กับ useCallback คือกุญแจสำคัญที่ทำให้แอปของคุณดูเป็นมืออาชีพและทำงานได้รวดเร็ว ลองเริ่มจากโปรเจกต์เล็กๆ ของคุณก่อน อย่าเพิ่งรีบเอาไปใช้กับทุกส่วนในแอปขนาดใหญ่

ตัวอย่างการนำไปใช้จริง: ถ้าคุณต้องทำตาราง (Table) ที่แสดงข้อมูลสินค้า พนักงาน และลูกค้า ให้คุณลองเขียน <Table<T> /> ขึ้นมาเพียงตัวเดียว แล้วใช้ renderItem เพื่อกำหนดว่าจะแสดงหัวข้ออะไรในแต่ละคอลัมน์ คุณจะพบว่าโค้ดของคุณดูสะอาดขึ้นและดูแลรักษาง่ายกว่าเดิมมาก

การเป็นโปรแกรมเมอร์ไม่ใช่แค่การเขียนให้โค้ดรันได้ แต่คือการเขียนให้คนอื่น (และตัวคุณเองในอนาคต) อ่านเข้าใจและทำงานได้เร็ว ฝึกใช้เครื่องมือเหล่านี้ให้เป็นนิสัย แล้วคุณจะก้าวข้ามจากมือใหม่ไปสู่ระดับมืออาชีพได้เร็วกว่าคนอื่นแน่นอนครับ

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

วิธีเช็ก Type ด้วย tsc --noEmit และตั้งค่า Environment Variables ใน React TypeScript ก่อน Deploy
React TypeScript

วิธีเช็ก Type ด้วย tsc --noEmit และตั้งค่า Environment Variables ใน React TypeScript ก่อน Deploy

ไม่อยากให้แอปพังตอน Deploy ต้องอ่าน! สอนวิธีใช้ tsc --noEmit ตรวจสอบข้อผิดพลาดในโปรเจกต์ React TypeScript พร้อมวิธีตั้งค่า Environment Variables ให้ปลอดภัย

1 month ago 8 นาที
22 views
React TypeScript Workshop: จัดการ State, Form และ API ให้ปลอดภัยแบบมือโปร
React TypeScript

React TypeScript Workshop: จัดการ State, Form และ API ให้ปลอดภัยแบบมือโปร

เรียนรู้วิธีเขียน React ด้วย TypeScript ให้โค้ดสะอาดและลดบั๊ก ตั้งแต่การจัดการ Form ด้วย React Hook Form ไปจนถึงการดึงข้อมูล API และทำ Global State แบบ Type Safe

1 month ago 8 นาที
24 views
React TypeScript Workshop: เริ่มต้นเขียนโค้ดแบบมือโปรด้วย Type-First Architecture
React TypeScript

React TypeScript Workshop: เริ่มต้นเขียนโค้ดแบบมือโปรด้วย Type-First Architecture

อยากเขียน React ให้เก่งและบั๊กน้อยลงไหม? มาเรียนรู้วิธีวางโครงสร้างข้อมูล (Type-First) และสร้าง UI Component ที่นำกลับมาใช้ใหม่ได้จริง

1 month ago 7 นาที
23 views