Day23 - 在 XState 中的平行式状态 Parallel States

还记得我们在 Day 13 的例子吗?

有个 Input 的 UI 元件,且它有以下 [Invalid / Valid]、[Disabled / Enabled]、[Changed / Unchanged],这 3 类型的特点

https://ithelp.ithome.com.tw/upload/images/20210927/20130721esiomcqiFn.png
我们假设

  • 有没有 Invalid 不影响会不会 Disabled;
  • 有没有 Invalid 不影响会不会 Changed;
  • 有没有 Disabled 不影响会不会 Changed...
    并且假如我们说这 3 类特徵任意搭配组合也都是合理的...

今天就即将在 XState 实作,写出 machineConfig 来!
你说 XState 的 config 如何描述 Parallel State 呢?

1. 如何在 XState 描述 Parallel States

以下是一个 一般的 FSM

 {
    id: "myId",
    initial: "state1",
    states: {
      state1: {
        on: {
          event1: { target: "state2" }
        }
      },
      state2: {
        on: {
          event2: { target: "state1" }
        }
      }
    }
  }

我们只要在 states 前面加上一组 [key / value] -> type: 'parallel', ,并在上面原本 state1state2 之间,原本直接写下 [on + event1], [on + event2] 改成另外一组新的子状态机定义

TLDR 视觉化互动状态机

  id: "myId",
+ type: "parallel",
- initial: "state1",
  states: {
    state1: {
+     initial: "state1-1",
+     states: {
+       "state1-1": {
+         on: {
+           "event1-1": { target: "state1-2" },
+         },
+       },
+       "state1-2": {
+         on: {
+           "event1-2": { target: "state1-1" },
+         },
+       },
+     },
    },
    state2: {
+     initial: "state2-1",
+     states: {
+       "state2-1": {
+         on: {
+           "event2-1": { target: "state2-2" },
+         },
+       },
+       "state2-2": {
+         on: {
+           "event2-2": { target: "state2-1" },
+         },
+       },
+     },
    },
  },
});

https://ithelp.ithome.com.tw/upload/images/20211008/20130721pWQS67KCiB.png

如此就可以完成一个简易的平行状态机


题外话,XState 官方也有提供视觉化工具 Visualizer ,让你可以简易的撰写完 machineConfig 後,就能直接看到 State Chart 并且能与之互动

刚刚的范例可参考视觉化互动状态机

另外我们现在会看 Visualizer 上使用到旧版 API Machine,其实 XState 目前也已经有新版的 Visualizer 了,只不过我还不太熟悉如何分享,所以在这边先用旧版的分享

旧版 https://xstate.js.org/viz
新版 https://stately.ai/viz

除了新版的 Visualizer,官方也提供了 DX 更好的 tool, inspect 套件,也希望能在这次铁人赛有机会能介绍到


2. 完成需求


const inputMachine = createMachine({

  id: "inputMachine_v1",
  type: "parallel",

  states: {
    valid: {
      initial: "valid",
      states: {
        invalid: {
          on: {
            VALIDATE: { target: "valid" },
          },
        },
        valid: {
          on: {
            INVALIDATE: { target: "invalid" },
          },
        },
      },
    },
    enabled: {
      initial: "enabled",
      states: {
        disabled: {
          on: {
            ENABLE: { target: "enabled" },
          },
        },
        enabled: {
          on: {
            DISABLE: { target: "disabled" },
          },
        },
      },
    },
    changed: {
      initial: "unchanged",
      states: {
        unchanged: {
          on: {
            CHANGE: { target: "changed" },
          },
        },
        changed: {
          on: {
            REVERT_CHANGE: { target: "unchanged" },
          },
        },
      },
    },
  },
});

Demo Visualizer

https://ithelp.ithome.com.tw/upload/images/20211008/201307211J6UpoVUtY.png

如此我们便完成了 Day 13 的例子。

参考资料

https://xstate.js.org/docs/guides/parallel.html


<<:  Day23 - [丰收款] 以Django Web框架实作永丰API线上支付模拟情境(4) - 信用卡刷卡结果

>>:  Facades

【Day 10】- 你的爬虫是哪一类的? (网路爬虫的类型)

前情提要 前一篇文章带大家看了 BeautifulSoup 库的使用,用他来做资料清洗,使我们真正想...

overseas education consultants in delhi

overseas education consultants in delhi Abroad edu...

[Day4] 学 Bootstrap 是为了走更长远的路 ~ 基本篇

前言 昨天的文章有提到接下来会介绍几个 Bootstrap 我到现在还是很常用的语法, 但你可能会说...

Day17 参加职训(机器学习与资料分析工程师培训班),Python程序设计

练习使用selenium来登入FB from selenium import webdriver d...

[PoEAA] Domain Logic Pattern - Domain Model

本篇同步发布於个人Blog: [PoEAA] Domain Logic Pattern - Doma...