อย่าสับสนระหว่าง Data Shape กับ State Shape
เมื่อคุณสร้างฟอร์มด้วย React คุณมักจะรวมทุกอย่างไว้ใน state object ขนาดใหญ่เพียงอันเดียว
คุณเห็นส่วนของ Address ใน UI ของคุณ คุณจึงสร้าง address object ไว้ใน state ของคุณ มันดูเป็นระเบียบและดูสะอาดตา
แต่นี่คือกับดัก
ปัญหาไม่ได้อยู่ที่ React แต่อยู่ที่ shape ของ state ของคุณต่างหาก
ฟอร์มไม่ใช่ข้อมูลที่หยุดนิ่ง (static data) แต่เป็นระบบที่มีการโต้ตอบ (interactive systems) ผู้ใช้ไม่ได้อัปเดตฟอร์มทีละส่วน (section) แต่พวกเขาอัปเดตทีละฟิลด์ (field)
ทำไม nested state ถึงส่งผลเสียต่อโปรเจกต์ของคุณ:
- การอัปเดตจะกลายเป็นเรื่องหนัก การจะเปลี่ยนชื่อเมืองเพียงชื่อเดียว คุณต้องสร้าง object ของเมือง, ของ address และของฟอร์มในระดับบนสุดขึ้นมาใหม่ทั้งหมดเพื่อรักษาความเป็น immutability
- ความซับซ้อนจะลุกลาม เมื่อฟอร์มใหญ่ขึ้น ตรรกะการ validation และการ rendering ของคุณจะจัดการได้ยากขึ้น
- การ re-render เพิ่มขึ้น การเปลี่ยนค่าที่ซ้อนอยู่ (nested value) เพียงค่าเดียวจะสร้าง object reference ใหม่ ซึ่งอาจกระตุ้นให้เกิดการอัปเดตที่ไม่จำเป็นไปทั่วทั้ง component tree ของคุณ
- ภาระทางความคิดเพิ่มขึ้น คุณจะเลิกคิดถึงผู้ใช้งาน แต่เริ่มไปคิดถึงเรื่อง object paths แทน
ฟอร์มขนาดเล็กอาจจะไม่เป็นปัญหามากนัก แต่ฟอร์มในระดับ Product นั้นไม่ใช่
ฟอร์มที่ใช้งานจริง (production form) จำเป็นต้องมีการ validation, autosave และ conditional logic หากคุณสร้างสิ่งเหล่านี้บน object ที่ซ้อนกันลึกๆ ทุกฟีเจอร์ใหม่ที่เพิ่มเข้ามาจะรู้สึกว่าต้องแลกมาด้วยต้นทุนที่สูง (expensive)
ทางออกคือการออกแบบ state ตามลักษณะการเปลี่ยนแปลงของข้อมูล ไม่ใช่ตามลักษณะที่มันปรากฏ
การใช้ state shape ที่แบนราบ (flatter) มากขึ้น ให้ประโยชน์ดังนี้:
- อัปเดตได้เร็วขึ้น คุณเขียนโค้ดน้อยลงในการเปลี่ยนค่าเพียงค่าเดียว
- ดีบั๊กง่ายขึ้น การอัปเดตจะอยู่แค่ในขอบเขตที่จำกัดและคาดเดาได้
- ขอบเขตของ component ดีขึ้น คุณสามารถส่งข้อมูลชิ้นเล็กๆ แทนที่จะต้องส่ง object ขนาดใหญ่
อย่าทำให้ทุกอย่างแบนราบโดยไม่ลืมหูลืมตา หากข้อมูลไม่ค่อยมีการเปลี่ยนแปลงและมักจะเคลื่อนที่ไปพร้อมกันเสมอ การทำ nesting ก็ถือว่าใช้ได้ แต่จงอย่าทำ nesting กับส่วนของฟอร์มที่มีการเปลี่ยนแปลงอยู่ตลอดเวลา
ถามคำถามเหล่านี้กับตัวเองก่อนเริ่มเขียนโค้ด:
- ฟิลด์ไหนที่มีการเปลี่ยนแปลงบ่อยที่สุด?
- ส่วนไหนที่ต้องการการ validation แบบแยกอิสระ?
- การอัปเดตส่วนไหนที่ต้องแยกขาดจากส่วนอื่นๆ ของ UI?
หากการอัปเดตฟิลด์หนึ่งรู้สึกยากกว่าตัวการเปลี่ยนแปลงเอง นั่นแสดงว่าโครงสร้าง state ของคุณคือปัญหา
เลิกออกแบบ state ตาม UI ของคุณ แต่เริ่มออกแบบตามพฤติกรรมของผู้ใช้งานแทน
