[note] State Machines
此篇為各筆記之整理,非原創內容,資料來源可見下方連結與文後參考資料:State Machines in JavaScript with XState, v2 @ Frontend Masters
TL;DR
State and Event
interface Typestate<TContext> {
value: StateValue; // 目前的 state
context: TContext;
event: TEvent; // 收到的事件
matches(parentStateValue): boolean; // 是否是屬於某個 parentState 底下的 state
can(event: TEvent): boolean; // 接收到該 event 某會不會有 transition
}
interface EventObject {
type: string;
}
Machine:
const machine = createMachine({
/*...*/
});
// 使用 transition 可以用來檢視從某 state 接收到特定 event 時會轉換成什麼 state
const nextState = machine.transition('playing', {
type: 'PAUSE',
});
Service:
// 使用 service 可以實際操作某個完整的狀態圖
const service = interpret(machine, { devTools: true }).start();
// 取得當前的 state
service.state;
// 使用 send 來轉換狀態
service.send({ type: 'LOADED' });
service.subscribe((state) => {
state.can({ type: 'PLAY' }); // 收到該 event 後會不會有對應的 transition
state.value;
});
Debug
可以使用 inspect 工具,它會在瀏覽器開啟另一個分頁,同步顯示當前的狀態,而且它是雙向的,也就是說:
- 從 App 改變狀態,inspector 的狀態也會改變
- 從 inspector 改變狀態,App 的狀態也會改變
import { interpret, inspect } from '@xstate/inspect';
inspect({
iframe: false,
url: 'https://stately.ai/viz?inspect',
});
const service = interpret(playerMachine, { devTools: true }).start();
Actions
Actions @ XState