xstate 初探 (2): 使用 spawn / send 建立 widget state machine 與父層傳遞事件溝通
基本上當專案的元件複雜度都高到一個程度時,只有一個 state machine 是無法滿足專案的狀態變化需求,所以需要再規劃架構時對每個元件的複雜度建立不同的 state machine.。所以本文目的是實作父層如何建立子層的 state machine 並互相溝通。
在實作前可以先大致了解一下 spawn actor
章節。xstate 除了核心的 fsm 架構之外,還引用了 actor model
來達到關注點分離。
關於 actor model 幾項特性:
- actor 可以建立一或多個 actor.
- actor 透過 message ( 在 xstate 裡指的是 event )與其他 actor 溝通。
- actor 可以指定如何處理下一個 message.
- actor 有自己的 local state 並且處於 isolate 狀態。
- actor 是輕量的,容易被建立。
也因為 actor model
特性,所以 machine 與 machine 之間溝通透過 event 來傳遞,並在各自的 local state 做資料處理。
actor model 相關資料放在文末
實作 Widget List
以一個簡單的 widget list 為例,父容器 List 可以透過事件發送給子容器 Widget 更新資料,而子容器的 Widget 可往上發送事件給父層刪除資料。
先看已完成的範例: Widget List 與 Widget 有各自獨立的 state machine. 並且有各自的 loading / idle 狀態。widget list 可以統一發送更新時間的事件, 而 widget 的移除按鈕點選可呼叫上層 machine event 刪除 widget 相關 context 資料。
主要的程式碼是著重在 widgetListMachine
跟 widgetMachine
這兩個 machine config.
要點:
- 上層建立子 widget 的 state machine: 上層的 widgetListMachine 在 loading state 透過
invoking promise
跟後端要相關資料,並在onDone
時透過spawn
建立的actor
+Machine.withContext
建立 widgetMachine 及初始 context. - 上層發送事件給 widget: 請參考 widgetListMachine
updateTimeToWidgets
action,使用pure action
建立動態 actions 並從 context 取出 actor 逐一send action
。而在 widgetMachine updateTime action 則收到發出的 update Time event 並取得更新資料。 - widget 發送事件給上層: 請參考 widgetMachine 的 remove action 透過
sendParent
送出事件並 tigger widgetListMachine 的removeWidget
action. 然後再更新上層的 context 資料移除掉 widget.
reference:
actor model reference: