จัดการ Form State และ Validation ใน React ไม่ให้โค้ดรก
แยก values, errors, touched และ submit state ออกจากกัน ใช้ validation function ที่อ่านง่าย และแสดงข้อความผิดพลาดในจังหวะที่เป็นมิตรกับผู้ใช้

ภาพรวม
ฟอร์มใน React มักเริ่มจากของง่าย input หนึ่งช่อง state หนึ่งตัว แต่พอมี email, password, confirm, error, touched, loading โค้ดเริ่มกลายเป็นเส้นสปาเกตตี 🍝
หลักคิดคืออย่าให้ “ค่าฟอร์ม” ปนกับ “กฎธุรกิจ” และ “ข้อความ UX” value ควรอยู่ที่เดียว validation ควรเป็นฟังก์ชันอ่านง่าย การแสดง error ควรเกิดในจังหวะที่ผู้ใช้รับไหว ไม่ใช่แดงทั้งหน้า ตั้งแต่ยังไม่พิมพ์อะไร
เก็บ form เป็น object เช่น name, email, password แล้วใช้ handleChange กลางตัวเดียว อาศัย name ของ input เป็น key เวลามี field ใหม่ โค้ดไม่บวม เขียน setState แบบ prev => ({ ...prev, [name]: value }) สั้น และไม่ทำค่าช่องอื่นหาย
Validation ที่ UX ดี ไม่ได้แปลว่าตรวจทุกตัวอักษรแล้วตะโกนทันที required อาจรอ blur ก่อนค่อยบอก username availability ควร debounce แล้วค่อยยิง API แต่ตอน submit ต้อง validate ทั้งฟอร์มอีกครั้งเสมอ เพราะ client state เชื่อใจไม่ได้ 100%
รูปแบบที่ช่วยให้ code ไม่รกคือทำ validate(form) ให้คืน object ของ errors เช่น { email: 'รูปแบบอีเมลไม่ถูกต้อง' } ถ้าไม่มี error ก็เป็น object ว่าง component จะไม่ต้องรู้รายละเอียดกฎทั้งหมด แค่ถามว่า errors.email มีไหม แล้ว render ข้อความ
อีกตัวที่ควรมีคือ touched เพราะ error กับ touched เป็นคนละเรื่อง email อาจผิดจริง แต่ถ้าผู้ใช้ยังไม่เคยแตะช่องนั้น การโชว์ error จะเหมือนโดนดุ เงื่อนไข touched.email && errors.email จะนุ่มกว่าเยอะ 🙂
ปุ่ม submit ก็เป็น UX ตอนกำลังส่งควร disable และเปลี่ยนข้อความเป็น “กำลังบันทึก...” กันการกดซ้ำ แต่ไม่จำเป็นต้อง disable แค่เพราะ form ยังไม่ valid เสมอไป บางครั้งให้กดแล้วเห็น error ชัด ๆ ดีกว่าเงียบจนไม่รู้ว่าติดอะไร
ถ้าฟอร์มซับซ้อน ใช้ React Hook Form ได้ แต่ไม่ควรใช้เพื่อหนีพื้นฐาน ไลบรารีช่วยลด re-render แต่กฎเดิมยังอยู่ แยก state, validation, การแสดงผล
microcopy ก็สำคัญ “รหัสผ่านต้องมีอย่างน้อย 8 ตัว” ดีกว่า “Invalid password” error ควรอยู่ใกล้ field มี aria-invalid ถ้าทำได้ เพราะ UX ที่ดีรวม accessibility ด้วย
สรุปคืออย่าเขียน validation กระจายตาม onChange ทุกช่อง อย่าโชว์ error เร็วจนรบกวน ทำ validate ให้บริสุทธิ์ ใช้ touched คุมจังหวะ จัด submit state ให้ชัด ฟอร์มจะอ่านง่าย แก้ง่าย และผู้ใช้ไม่หงุดหงิดครับ ✨
แนวทางนำไปใช้
- นำแนวคิดจากโพสต์นี้ไปทดลองกับงานจริงของคุณ
- แยกเป็นขั้นตอนเล็ก ๆ แล้วทำทีละส่วน
- บันทึกผลลัพธ์และสิ่งที่เรียนรู้เพื่อต่อยอด
สรุป
แยก values, errors, touched และ submit state ออกจากกัน ใช้ validation function ที่อ่านง่าย และแสดงข้อความผิดพลาดในจังหวะที่เป็นมิตรกับผู้ใช้