ช่วงนี้มีโอกาสมาเขียนและ 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

มีอีกเรื่องที่สำคัญคือ
ควรแยกส่วนของ business logic ออกไปจาก component ด้วยนะ
แต่เรื่องนี้จะไม่อธิบายในส่วนนี้

มาถึงตรงนี้อาจจะนึกภาพตามไม่ออก

ดังนั้นมาดู code ตัวอย่างกันดีกว่า

ตัวอย่างเช่น ส่วนการแสดง comment ทั้งหมดใน blog นี้
เรามักจะพบเจอ component หน้าตาแบบนี้
นั่นคือ รวมทุกอย่างไว้ในเพียง component เดียว หรือเรียกว่า Fat component
ทำงานทั้งดึงข้อมูลจาก API มา และทำการแสดงผล ดังนี้

ผลที่ตามมาคือ CommentList เป็น React component ที่ไม่สามารถ reuse ได้เลย
นั่นหมายความว่า
ถ้าต้องการแสดงข้อมูล comment เหมือนกันแต่ข้อมูลมาจาก API อื่น ๆ
จะไม่สามารถทำได้เลย

แต่ถ้าสังเกตุจะพบว่า
Component นี้ต้องการเพียงข้อมูลตามโครงสร้างที่ต้องการเท่านั้น
จากตัวอย่างคือ Array นั่นเอง
ดังนั้นจะดีกว่าไหม
ถ้าเราทำการส่งข้อมูลเข้ามายัง component ผ่านทาง PropsType

ดังนั้นจะดีไหม ถ้าเราแยกส่วนการดึงข้อมูลไปไว้ที่ component อื่น

โดยเราเรียก component นี้ว่า Container
ดังนี้

ส่วนที่ 1 คือ CommentListContainer
ทำหน้าที่ดึงข้อมูลจาก API
จากนั้นส่งข้อมูลไปยัง CommentList component ผ่านทาง PropsType

ส่วนที่ 2 คือ CommentList component
ทำหน้าที่แสดงผลข้อมูล comment ทั้งหมดออกมา
จากข้อมูล comment ที่ส่งผ่านมายัง PropsType

ผลที่ตามมาคือ
แยกการทำงานตามหน้าที่ที่ชัดเจน
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 ละ จะทำอย่างไรดี ?

Tags: