State Management
What is State ?
舉例來說:
- 使用者登入狀態
- 購物車狀態
- 訊息狀態
所有可互動的都有狀態
feat. 冠群的 slide
What is State Management ?
先由使用者互動改變狀態
畫面會依據不同的狀態去顯示
管理 資料 和 使用者操作事件 的互動流程
Redux
一個可預測的狀態容器
Flux Pattern Based
單向資料流
將狀態視作一連串的狀態流
每次的事件都是產生一個新的狀態

Before Flux : Only MVC

雙向資料綁定 → 連鎖更新
不容易去預測一個單一互動所造成的改變結果
MVC 只定義了三個角色的功能與關係
有了 FLUX 能更明確的定義「與資料互動的方式」
Single Store : Single Source of Truth
Redux

- Action 描述行為
- Reducer 通知改變
- Store 存值

Xstate
Finite State Machine (FSM) & Statechart based
Why Xstate ?
- 區分狀態 ( state ) 和 資料 ( context )
- 事先定義狀態(UI不會出現未知的狀態)
- XState Visualizer 可展示 StateChart
What is FSM ?
- 狀態總數(state)是有限的。
- 任一時刻,只處在一種狀態之中。
- 某種條件下,會從一種狀態轉變(transition)到另一種狀態。
有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型
例如:紅綠燈
( FSM 是很嚴謹的模型,這邊只是粗淺介紹 )
In Practice, we need ...
- 有限數量的狀態 (state)
- 有限數量的事件 (event)
- 一個初始狀態 (initial state)
- 一個轉換函式 (transition function)
- 具有 0 至 n 個最終狀態 (final state)
簡言之 就是 定義 各狀態 ( State ) 和 過渡方法 ( Action )
StateChart & Demo
import React from 'react';
import { useMachine } from '@xstate/react';
import { lightMachine } from './lightMachine';
function App() {
  const [state, send] = useMachine(lightMachine);
  return (
    <div className="App">
      {state.matches(LIGHT_STATES.RED) && <RedLight />}
      {state.matches(LIGHT_STATES.GREEN) && <GreenLight />}
      {state.matches(LIGHT_STATES.YELLOW) && <YellowLight />}
      <button
        onClick={() => {
          send(LIGHT_EVENTS.CLICK);
        }}
      >
        click me
      </button>
    </div>
  );
}import { Machine } from 'xstate';
const LIGHT_STATES = {
  RED: 'RED',
  GREEN: 'GREEN',
  YELLOW: 'YELLOW',
};
const LIGHT_EVENTS = {
  CLICK: 'CLICK',
};
export const lightMachine = Machine({
  initial: LIGHT_STATES.RED,
  states: {
    [LIGHT_STATES.RED]: {
      on: {
        [LIGHT_EVENTS.CLICK]: LIGHT_STATES.GREEN,
      },
    },
    [LIGHT_STATES.GREEN]: {
      on: {
        [LIGHT_EVENTS.CLICK]: LIGHT_STATES.YELLOW,
      },
    },
    [LIGHT_STATES.YELLOW]: {
      on: {
        [LIGHT_EVENTS.CLICK]: LIGHT_STATES.RED,
      },
    },
  },
});- State & Action 統一在 Machine 處理
- View 用 useMachine 來取得 service
Effect Handle
What is Effect ?
資料改變 或 使用者觸發事件 後產生的後續影響
Side Effect
運算的過程中,改變了系統狀態或是對外部世界進行交互。
如:非同步請求( Network Request )而產生的資料不一致
Redux

Redux Side Effect Management
本身自己不處理 Side Effect,依賴於 其他套件處理 ( middleware )

Redux thunk
import {
  createStore,
  combineReducers,
  compose,
  applyMiddleware,
} from 'redux';
import thunk from 'redux-thunk';
const store = createStore(combineReducers({
}), {}, compose(
  applyMiddleware(
    thunk,
  ),
));
export default store;
Xstate Effects
- 
Fire-and-forget effects ( synchronously  ) :
 Real-time 操作,執行動作後,直接改變狀態。
 
- 
Invoked effects ( asynchronously  ):
 可發送或接收非同步請求。
- entry : upon entering a state
- exit : upon exiting a state
- transition actions : when a transition is taken
- src : Promise handler
- resolve : onDone Transition
- reject : onError Transition
Redux
Xstate
- 生態系完整
- 僅需對資料流做控管
- State 和 context 定義清楚
- 使用情境可預測性高
- 可細拆分 machine
- 使用上較不直覺
- 狀態切換不明確
- 事先定義撰寫相對麻煩
- 狀態擴充複雜度易太高
優
優
缺
缺
One More Thing
Flow Control in FSM
By Routing
- " / commodity "
- " / commodity / : customerCode "
- " / commodity / : customerCode / shopping "
- " / commodity / : customerCode / payment "
- redirect to "/ commodity"
By Routing
- 傳遞資料不便
- 流程再多一點網址就會無限拉長
By FSM-Like Design
Shopping
Login
Payment
Pending
Success
idle
type Payload =
  | {
      step: 'idle';
    }
  | PayloadShopping
  | PayloadLogin
  | PayloadPayment
  | PayloadPending
  | PayloadSucess;interface PayloadShopping {
  step: 'shopping';
  customerInfo: CustomerInfo | undefined;
  items: ShoppingCartItemData[];
}
interface PayloadLogin extends Omit<PayloadShopping, 'step'> {
  step: 'login';
}
interface PayloadPayment extends Omit<PayloadLogin, 'step'> {
  accessToken: string;
  step: 'payment';
}
interface PayloadPending extends Omit<PayloadPayment, 'step'> {
  receivedAmount: number;
  step: 'pending';
}
interface PayloadSucess extends Pick<PayloadPending, 'receivedAmount'> {
  payment: CheckoutCashPaymentMutation_payment;
  step: 'success';
}{payload.step === 'idle' && (
  <EnterCustomerNoModal
    onNextStep={...}
  />
)}
{payload.step === 'shopping' && (
  <Shopping
    payload={...}
    onGoBack={...}
    onCheckout={...}
  />
 }
 {payload.step === 'login' && (
   <Login
      payload={...}
      onGoBack={...}
      onCheckout={...}
    />
 )}
 {payload.step === 'payment' && (
   <Payment
      payload={...}
      onGoBack={...}
      onPayment={...}
    />
 )}
 {payload.step === 'pending' && (
  <Pending
      payload={...}
      onGoBack={...}
      onSuccess={...}
    />
 )}
 {payload.step === 'success' && (
  <Success
      payload={...}
      onGoBack={...}
      onOk={...}
    />
 )}Flow Control
- 定義 state 和 context,好預測
- Component 採用依賴抽離模式
- 可讀性高,方便Debug & 測試
THANKS FOR LISTENING
State Management
By parkerhiphop
State Management
- 487
 
   
   
  