ช่วงนี้มีโอกาสมาเขียนและ review code ที่พัฒนาด้วย React กันนิดหน่อย
ปัญหาหลักที่พบเจอคือ
การออกแบบ react component สำหรับระบบงาน
ในแต่ละ component ทำงานมากเกินไป
ในแต่ละ component reuse ได้ยาก
ในแต่ละ component ทดสอบได้ยาก
ดังนั้นเรามาเข้าใจกับการออกแบบ component ที่น่าจะดีกันหน่อย
จากการค้นหา พบว่ามีการอธิบายเรื่องเหล่านี้ไว้เยอะเลย
ยกตัวอย่างเช่น เป้าหมายหลักคือ แยกหน้าที่การทำงานระหว่างการจัดการข้อมูลและการแสดงผลออกจากกัน นั่นคือ SRP (Single Responsibility Principle)สามารถสรุปแนวคิดง่าย ๆ ไว้ดังนี้
- Container หรือ Smart component มีหน้าที่สำหรับการจัดการข้อมูล บางครั้งเรียกว่า Stateful component
- Presentation หรือ Dumb component มีหน้าที่สำหรับแสดงผลซึ่งถูกสั่งหรือส่งข้อมูลมาจาก Container เท่านั้น บางครั้งเรียกว่า Stateless component
มาถึงตรงนี้อาจจะนึกภาพตามไม่ออก
ดังนั้นมาดู code ตัวอย่างกันดีกว่า ตัวอย่างเช่น ส่วนการแสดง comment ทั้งหมดใน blog นี้ เรามักจะพบเจอ component หน้าตาแบบนี้ นั่นคือ รวมทุกอย่างไว้ในเพียง component เดียว หรือเรียกว่า Fat component ทำงานทั้งดึงข้อมูลจาก API มา และทำการแสดงผล ดังนี้ [gist id="66e023c87ac7bd71ec87d5e5da4e9180" file="CommentListWithFatComponent.js"] ผลที่ตามมาคือ CommentList เป็น React component ที่ไม่สามารถ reuse ได้เลย นั่นหมายความว่า ถ้าต้องการแสดงข้อมูล comment เหมือนกันแต่ข้อมูลมาจาก API อื่น ๆ จะไม่สามารถทำได้เลย แต่ถ้าสังเกตุจะพบว่า Component นี้ต้องการเพียงข้อมูลตามโครงสร้างที่ต้องการเท่านั้น จากตัวอย่างคือ Array นั่นเอง ดังนั้นจะดีกว่าไหม ถ้าเราทำการส่งข้อมูลเข้ามายัง component ผ่านทาง PropsTypeดังนั้นจะดีไหม ถ้าเราแยกส่วนการดึงข้อมูลไปไว้ที่ component อื่น
โดยเราเรียก component นี้ว่า Container ดังนี้ ส่วนที่ 1 คือ CommentListContainer ทำหน้าที่ดึงข้อมูลจาก API จากนั้นส่งข้อมูลไปยัง CommentList component ผ่านทาง PropsType [gist id="66e023c87ac7bd71ec87d5e5da4e9180" file="CommentListContainer.js"] ส่วนที่ 2 คือ CommentList component ทำหน้าที่แสดงผลข้อมูล comment ทั้งหมดออกมา จากข้อมูล comment ที่ส่งผ่านมายัง PropsType [gist id="66e023c87ac7bd71ec87d5e5da4e9180" file="CommentListWithDumbComponent.js"] ผลที่ตามมาคือ แยกการทำงานตามหน้าที่ที่ชัดเจน CommentList component นั้นสามารถ reuse ได้ง่าย CommentList component นั้นสามารถทดสอบด้วยข้อมูลรูปแบบต่าง ๆ ได้ง่ายทั้ง success และ fail case ยังไม่พอนะ ในส่วนของ CommentList นั้น เราสามารถแยกการแสดงผลของแต่ละ comment ออกมาเป็น Component ได้อีก มันจะแยกกันไปถึงไหน !! ตัวอย่าง source code อยู่ที่ Github::Up1::Commentsสุดท้ายแล้ว
ขอแนะนำให้สร้าง Presentation หรือ Dumb component ให้เยอะที่สุดเท่าที่จะทำได้ แล้วมันจะทำให้ผลที่ออกมา ต่างจากเดินอย่างมาก อยากให้ component แสดงข้อมูลอะไร ก็ส่งเข้าไป อยากให้ component ทำงานตาม event/action ที่เกิดขึ้นอย่างไร ก็ส่งเข้าไป ไม่เชื่อก็ลองดูแต่ก็ใช่ว่าจะเหมาะไปกับทุกเรื่องนะ !!ขอให้สนุกกับการ coding ครับ
ปล. ถ้าใครไม่สนใจเรื่อง reuse ก็ทำแบบเดิมกันต่อไปนะสังเกตุไหมว่า ? มีการสร้าง component ต่าง ๆ เยอะเหลือเกิน ดังนั้นปัญหาที่ตามมาคือ โครงสร้างของ project เรานั้นเอง ทำอย่างไรที่จะจัดการแล้วไม่งง ? ทำอย่างไรที่จะจัดการแล้วไล่ code ได้ง่าย ? การจัดการ action/event ของแต่ละ component ละ จะทำอย่างไรดี ?