ทำไมคุณถึงต้องใช้ React Key Prop
คุณจะเห็นข้อผิดพลาดนี้ใน console: "Each child in a list should have a unique 'key' prop."
นักพัฒนาหลายคนมักจะมองข้ามมันไป ซึ่งนั่นเป็นความผิดพลาด เพราะคำเตือนนี้กำลังบอกคุณเกี่ยวกับปัญหาด้านประสิทธิภาพและบั๊กที่อาจเกิดขึ้นได้
key prop คืออะไร?
มันช่วยให้ React ระบุรายการเฉพาะเจาะจงในลิสต์ได้ โดยจะบอก React ว่ารายการไหนมีการเปลี่ยนแปลง, ย้ายตำแหน่ง หรือถูกลบออก หากไม่มี key ตัว React จะต้องทำการ re-render ลิสต์ทั้งหมดใหม่ทุกครั้งที่มีการเปลี่ยนแปลง ซึ่งจะทำให้แอปของคุณทำงานช้าลง
ลองนึกภาพห้องสมุดที่มีหนังสือ 1,000 เล่ม หากคุณเพิ่มหนังสือเล่มใหม่ลงไปตรงกลาง คุณจะต้องย้ายหนังสือเล่มอื่นๆ ทั้งหมดเพื่อจัดที่ว่างให้เล่มใหม่ key จะทำหน้าที่เหมือน ID เฉพาะสำหรับหนังสือแต่ละเล่ม ซึ่งช่วยให้ React ค้นหาตำแหน่งที่ถูกต้องได้โดยไม่ต้องย้ายสิ่งอื่นๆ ทั้งหมด
กระบวนการ Reconciliation
React ใช้ diffing algorithm เพื่อเปรียบเทียบ Virtual DOM ใหม่กับอันเก่า
- State เปลี่ยนแปลง
- React สร้าง tree ใหม่
- React เปรียบเทียบ tree โดยใช้ keys
- React อัปเดตเฉพาะ element ที่เปลี่ยนแปลงเท่านั้น
ข้อผิดพลาดที่พบบ่อย: การใช้ array index เป็น key
อย่าใช้ key={index} หากลิสต์ของคุณมีการเปลี่ยนแปลง เพราะถ้าคุณเพิ่มหรือลบรายการ index ของทุกรายการจะเลื่อนไปหมด ทำให้ React สับสนและทำการ re-render รายการที่จริงๆ แล้วไม่ได้เปลี่ยนแปลง ซึ่งเป็นการสิ้นเปลืองหน่วยความจำและทำให้เกิดบั๊กใน UI
วิธีแก้ไข:
- ใช้ ID ที่คงที่จากฐานข้อมูลของคุณ (เช่น
user.id) - ใช้ string ที่ไม่ซ้ำกันอย่าง
uuidหากข้อมูลของคุณไม่มี ID - หลีกเลี่ยงการใช้
Math.random()สำหรับ keys เพราะมันจะสร้าง ID ใหม่ในทุกๆ การ render ซึ่งจะบังคับให้ component ต้อง re-mount ใหม่ และทำให้เกิดอาการ UI กระพริบ
แนวทางปฏิบัติที่ดีที่สุด (Best practices):
- Keys ต้องมีความคงที่ (stable)
- Keys ต้องไม่ซ้ำกันในหมู่ sibling
- ใช้ ID จากฐานข้อมูลเพื่อให้ได้ประสิทธิภาพสูงสุด
ตารางเปรียบเทียบ Key:
• Database ID: แนะนำ เพราะมีความคงที่และรวดเร็ว • Array Index: ไม่แนะนำ เพราะทำให้เกิดบั๊กขณะทำการเรียงลำดับ (sorting) หรือกรองข้อมูล (filtering) • Math.random(): ควรหลีกเลี่ยง เพราะทำให้เกิดการ re-mount ที่ไม่จำเป็น
สรุปสำหรับขั้นตอนการทำงานของคุณ:
หากคุณเห็นข้อผิดพลาดนี้ แสดงว่า component ของคุณขาดตัวระบุตัวตนที่ถาวร ให้ตรวจสอบ API response ว่ามีฟิลด์ที่ไม่ซ้ำกัน เช่น email หรือ ID หรือไม่ การแก้ไขเรื่องนี้จะช่วยลดการ re-render ที่ไม่จำเป็นลงได้ถึง 30-40%
