redux00
จากงาน iOS Dev Meetup ครั้งที่ 4
มีหนึ่ง session พูดเรื่อง Redux – Brings Web Architecture to Mobile
เป็นสิ่งที่น่าสนใจมาก ๆ ที่สำคัญเข้าใจได้ไม่ยาก
ดังนั้นจึงนำมาสรุปนิดหน่อย ประกอบไปด้วย

  • ที่มาของแนวคิด Redux
  • Principle 3 ข้อ
  • โครงสร้างการทำงาน
  • Code ตัวอย่าง ซึ่งพัฒนาด้วยภาษา Swift

เริ่มต้นกันเลย

ที่มาของแนวคิด Redux

เป็นการนำเอาแนวคิดดีมากจาก framework/library/architecture ต่าง ๆ
ไม่ว่าจะเป็น

โดยที่ Redux จะเน้นในเรื่องของการจัดการ State หรือ สถานะต่าง ๆ ของ App
เนื่องจากในระบบงานนั้น จะมี State จำนวนมาก
ยิ่งระบบงานมีขนาดใหญ่ขึ้น ยิ่งมากขึ้นไปอีก
รวมทั้ง State ส่วนใหญ่มักจะถูกเปลี่ยนแปลงได้ตลอดเวลา (Mutable)
แถมยังมีความซับซ้อนแบบเท่าทวีคูณไปอีก
ทำให้จัดการได้ยากมาก ๆ
แสดงดังรูป

redux01

ดังนั้นจึงเกิดคำถามว่า
แล้วเราจะจัดการ State ต่าง ๆ เหล่านี้ของระบบอย่างไรดี ?
หนึ่งในคำตอบนั้นคือ Redux นั่นเอง

Principle 3 ข้อของ Redux ที่ต้องเข้าใจ

ประกอบไปด้วย

  1. Single source of truth
  2. State is read-only
  3. Changes are made with pure functions

1. Single source of truth
หมายความว่า State ต่าง ๆ ของระบบงาน
จะถูกจัดเก็บไว้เพียงที่เดียวเท่านั้น
โดยที่จัดเก็บจะเรียกว่า Store
อยู่ในรูปแบบของ object tree

2. State is read-only
สถานะต่าง ๆ ไม่สามารถเปลี่ยนแปลงได้
ดังนั้นเมื่อเกิดเหตุการณ์ หรือ Action ขึ้นมา
จะทำการสร้าง State ใหม่ขึ้นมาต่อจาก State เดิม
โดยไม่ทำการแก้ไข State เดิม
ทำให้เราสามารถจัดเก็บ State และ Replay ได้อีกด้วย
นั่นคือ เราสามารถ recovery state ต่าง ๆ ได้
รวมทั้งง่ายต่อการทดสอบอีกด้วย

3. Changes are made with pure functions
เมื่อมีเหตุการณ์ขึ้นมาแล้ว State ต่อไปคืออะไร ?
นั่นเป็นหน้าที่ของ Reducer
ซึ่ง Reducer นั้นจะเป็น pure function
โดยพิจารณาจาก State ปัจจุบัน + Action ทำให้จะได้ State ต่อไปขึ้นมา
ซึ่ง Reducer จะส่ง State ใหม่ออกมาเท่านั้น
โดยไม่เปลี่ยนแปลง State ก่อนหน้าโดยเด็ดขาด

คำถามคือ Pure function คืออะไร ?
ดังนั้นต้องมี Inpure function แน่นอน
ประเด็นหลักมันคืออะไรกันล่ะ เกิดมาเพิ่งเคยได้ยิน !!

คำตอบง่าย ๆ คือ
เป็น function/method ที่ไม่ก่อให้เกิดผลกระทบ (Side Effect) ใดต่อระบบ
นั่นคือไม่ทำการเปลี่ยนแปลงข้อมูลใด ๆ ที่ส่งเข้าไปยัง function/method
และจะส่งค่าใหม่ออกมาเท่านั้น
แนะนำให้ดูจาก VDO เรื่อง JavaScript Redux pure and impure function

แสดงดังตัวอย่าง

โครงสร้างการทำงานของ Redux (Flow)

ส่วนการทำงานต่าง ๆ ของ Redux จะประกอบไปด้วย

  • State คือ สถานะต่าง ๆ ของการทำงาน
  • Action คือ เหตุการณ์ต่าง ๆ ที่เกิดขึ้น
  • Store คือ ที่จัดเก็บ State ต่าง ๆ หรือสามารถเรียกว่าเป็น State Container และ notify ไปยังส่วนต่าง ๆ ที่ subscribe ไว้
  • Reducer คือ pure function ที่ทำการสร้าง State ถัดไปโดยพิจารณาจาก State ปัจจุบัน และ Action ที่เกิดขึ้น

ขั้นตอนการทำงานของ Redux จะเป็นแบบ Unidirectional data flow
หรือการทำงานแบบทางเดียว ไม่มีย้อนกลับ
แสดงดังรูป

redux02

คำอธิบาย

  1. เมื่อเกิด Action ต่าง ๆ ขึ้นมา ไม่ว่าจะเกิดจาก view/data source หรืออะไรก็ตามที่ต้องการเปลี่ยนแปลง State จะถูกส่งมาที่ Store
  2. จากนั้น Store จะทำการเรียกใช้งาน Reducer โดยส่ง State ปัจจุบัน และ Action ไปให้
  3. ทำการเรียก Reducer เพื่อทำงานตาม Action
  4. จากนั้น Reducer ทำการส่ง State ใหม่กลับมา
  5. ส่ง State ใหม่กลับไปให้ Store
  6. จากนั้น Store จะทำการ notify หรือแจ้งไปยังส่วนการทำงานต่าง ๆ ที่ subscribed ไว้ เพื่อทำการ update ต่อไป เช่น การแสดงผล เป็นต้น
  7. ส่วนการแสดงผล หรือ data source อาจจะสร้าง Action ใหม่ ๆ ขึ้นมาได้อีก เช่น จากผู้ใช้งาน และ ข้อมูลจากภายในระบบ เป็นต้น

และทำแบบนี้วนไปเรื่อย ๆ ในทุก ๆ Action

สังเกตุไหมว่า
การจัดการ State นั้นมันอยู่ระหว่าง View กับ Model นั่นเอง

มาลองเขียน Code ด้วยภาษา Swift กันบ้าง

Source code มาจาก meet up นั่นเอง ReduxPlayground
เป็นตัวอย่างการสร้าง TODO App
จึงนำมาสรุปใหม่นิดหน่อย

1. เริ่มด้วยการกำหนด Action ก่อน
ว่าใน app ของเรานั้นจะมี Action หน้าตาอย่างไร
และมี Action อะไรบ้าง
ตัวอย่าง code จะมี Add TODO Action ก่อน

2. ทำการสร้าง State ขึ้นมา
โดยเราสามารถกำหนดโครงสร้างของ State ในรูปแบบใด ๆ ก็ได้
จากตัวอย่าง State จะประกอบไปด้วย

  • List ของ TODO
  • การเปลี่ยนแปลง

3. สร้าง Reducer function ขึ้นมา
โดยมี input คือ State และ Action
และทำการส่งค่า State ใหม่กลับไป

4. สร้าง Store ซึ่งเป็น Container ของการทำงานเลย
มีส่วนการทำงานต่าง ๆ ดังนี้

  • ทำการเก็บ State ทั้งหมดของระบบ
  • อนุญาตให้ getState() ได้
  • สามารถส่ง Action เข้ามาได้
  • สามารถ subscribe ได้

โดยมีโครงสร้างดังนี้

จากนั้นทำการสร้าง Store ขึ้นมา

5. เมื่อทุกอย่างพร้อม ก็นำมารวมกันเพื่อใช้งาน

จากนั้นจึงนำไป integrate เข้ากับ ViewController ในการพัฒนา App ต่อไป

มาถึงตรงนี้คิดว่า น่าจะทำให้เราเข้าใจกับแนวคิดของ Redux มากขึ้นบ้าง

ซึ่งการเริ่มต้นด้วยการเขียน code เองตั้งแต่ศูนย์
มันทำให้เราเข้าใจแนวคิดมากขึ้น
ลองดูกันครับ

ปล. ได้ยินมาอีกว่า Kotlin มันก็คล้าย ๆ กับ Swift นะ
ดังนั้นสามารถเอาควาวมรู้เหล่านี้ไปเขียนด้วย Kotlin
สำหรับการพัฒนา Android app ได้เลย
มันน่าสนใจมาก ๆ