☰
XState v5 状态管理与编排实战:状态机、Statechart 与 Actor 模型的完整指南
2026/9/30 6:44:10 网站建设 项目流程
  • 前端
  • 后端

【免费下载链接】xstate

State machines, statecharts, and actors for complex logic

项目地址:https://gitcode.com/gh_mirrors/xs/xstate
点击查看免费下载

XState 是面向 JavaScript 和 TypeScript 应用的状态管理与编排解决方案,采用事件驱动编程、有限状态机(FSM)、Statechart(状态图)与 Actor 模型,以可预测、健壮且可视化的方式处理复杂逻辑。本文以本仓库根目录 README.md 为主线,结合 packages/core 的源码实现与 examples 中的真实示例,系统讲解如何选型、建模与运行状态机,帮助读者掌握从createMachine建模、createActor运行,到setup注入副作用、@xstate/store轻量状态管理的完整实战路径。

XState 是什么

XState 是一个面向 JS/TS 应用的状态管理和编排解决方案,核心包零依赖,既适用于前端也适用于后端应用逻辑(例如 examples/express-workflow 与 examples/mongodb-credit-check-api 展示了后端编排场景)。

它通过事件驱动编程、状态机、Statechart 与 Actor 模型,把应用逻辑建模为actors(参与者)和state machines(状态机),从而让复杂逻辑变得可预测、健壮且可视化。Statechart 是一种用于形式化建模有状态、响应式系统的体系,可以声明式地描述从单个组件到整体应用逻辑的行为。

从源码看,XState 的核心结构十分清晰(见 packages/core/src):

  • createMachine.ts:根据配置创建“纯逻辑”的状态机(Statechart);
  • createActor.ts:把逻辑实例化为可运行、可收发事件的 Actor;
  • StateMachine.ts:状态机运行时,实现ActorLogic接口;
  • setup.ts:集中声明 actors、actions、guards、delays 等实现,获得更强的类型推导;
  • State.ts 与 stateUtils.ts:快照(Snapshot)与微观/宏观步进(microstep/macrostep)等转换机制。

XState 的设计受到 SCXML 规范 与之对应)。

我应该使用哪个包

根据需求选择,两者可以组合使用,但并非互相依赖:

包适用场景
@xstate/store简单的事件驱动状态管理,体积 <1kb,TypeScript 类型推导优秀,思路接近 Redux/Zustand。如果你只需要一个 store,从这里开始。
xstate(核心包)状态机、Statechart、Actor、副作用与复杂应用逻辑编排

两者可以很好地配合使用,但不需要为了使用其中一个而安装另一个。当你的逻辑变复杂时,可以从@xstate/store平滑升级到完整的 XState 状态机。

超快速开始:第一个状态机

安装核心包:

npm install xstate

下面是一个完整的计数器 Toggle 状态机(README 官方示例,仓库 examples/toggle/src/toggleMachine.ts 中也有无 context 的简化版本):

import { createMachine, createActor, assign } from 'xstate'; // 定义状态机(纯逻辑) const toggleMachine = createMachine({ id: 'toggle', initial: 'inactive', context: { count: 0 }, states: { inactive: { on: { TOGGLE: { target: 'active' } } }, active: { entry: assign({ count: ({ context }) => context.count + 1 }), on: { TOGGLE: { target: 'inactive' } } } } }); // 创建 Actor(状态机逻辑的实例,类似于 store) const toggleActor = createActor(toggleMachine); toggleActor.subscribe((state) => console.log(state.value, state.context)); toggleActor.start(); // => logs 'inactive', { count: 0 } toggleActor.send({ type: 'TOGGLE' }); // => logs 'active', { count: 1 } toggleActor.send({ type: 'TOGGLE' }); // => logs 'inactive', { count: 1 }

从源码理解这套流程

  • createMachine只负责建模。源码注释明确指出:"The state machine represents the pure logic of a state machine actor"(状态机表示状态机 Actor 的纯逻辑),见 createMachine.ts。它接收MachineConfig,返回一个StateMachine实例。
  • createActor负责运行。在 createActor.ts 中,createActor(logic, options)直接new Actor(logic, options)。Actor 是"一个正在运行的过程,可以接收事件、发送事件,并根据收到的事件改变自身行为,进而产生 Actor 外部的影响",见 createActor.ts。
  • start()、send()、subscribe()构成运行闭环。start()会注册 actor、以初始化事件驱动首次快照更新并启动 mailbox(事件队列);send()通过this.system._relay把事件投入 mailbox,由_process调用logic.transition(snapshot, event, scope)计算下一个快照;subscribe()则把观察者登记到observers集合中,在update()里逐个通知,见 createActor.ts。
  • assign是 context 更新机制。active状态的entry: assign(...)在进入该状态时执行,更新context.count。

核心 API 纵深:createMachine、createActor 与 setup

createMachine:声明式配置

createMachine的核心配置项与 README 示例一一对应:

  • id:机器唯一标识,用于可视化与引用;
  • initial:初始状态名;
  • context:可变的扩展状态(extended state),即业务数据;
  • states:状态集合,每个状态可配置:
    • on:事件到转换的映射,{ target: 'active' }或简写'active';
    • entry/exit:进入/离开状态时执行的动作(如assign);
    • invoke:调用子 Actor(见下文 fetch 示例);
    • after:延迟转换(如失败后 1000ms 自动重试);
    • always:无条件/带守卫的瞬时转换。

从源码看,createMachine本质是new StateMachine(config, implementations)(见 createMachine.ts),StateMachine实现了ActorLogic接口,负责转换计算、初始微步进、状态节点解析等,见 StateMachine.ts。

createActor:Actor 选项与生命周期

createActor(logic, options)支持以下选项(见 createActor.ts):

选项作用
input传递给逻辑的输入数据,由logic.getInitialSnapshot(scope, input)消费
id相对父级的唯一标识,缺省时使用sessionId
parent父 Actor 引用,缺省时创建以自己为根的新 Actor 系统
clock负责设置/清除延迟事件定时器的时钟,默认使用全局setTimeout/clearTimeout
logger日志函数,默认console.log
syncSnapshot是否将活跃快照同步中继给父级
snapshot/state用于从持久化快照恢复(rehydration)
devTools是否连接 DevTools 适配器

生命周期要点:

  • 创建 Actor 会隐式创建一个以该 Actor 为根的系统(createSystem),任何从根 Actor spawn 出来的后代都属于该系统;
  • 必须先start()再send();根 Actor 可以stop(),同时停止整个系统及其所有 Actor;
  • subscribe(observer)返回带unsubscribe()的订阅对象,Actor 停止时所有观察者会被自动退订;
  • 状态快照可以通过getSnapshot()同步读取,持久化用getPersistedSnapshot();
  • 旧版interpret()与Interpreter已废弃,直接别名到createActor/Actor(见 createActor.ts)。

setup:集中声明实现,获得最佳类型推导

对于真实应用,推荐用setup()集中声明副作用与类型,再通过.createMachine(...)建模。源码位于 setup.ts,它把actors、actions、guards、delays等实现注册为可被机器按名字引用的实现表。

以 examples/fetch/src/fetchMachine.ts 为例,展示了异步取数的完整建模:

import { assign, fromPromise, setup } from 'xstate'; export const fetchMachine = setup({ types: { context: {} as { name: string; data: { greeting: string } | null; } }, actors: { fetchUser: fromPromise(({ input }: { input: { name: string } }) => getGreeting(input.name) ) } }).createMachine({ initial: 'idle', context: { name: 'World', data: null }, states: { idle: { on: { FETCH: 'loading' } }, loading: { invoke: { src: 'fetchUser', input: ({ context }) => ({ name: context.name }), onDone: { target: 'success', actions: assign({ data: ({ event }) => event.output }) }, onError: 'failure' } }, success: {}, failure: { after: { 1000: 'loading' }, on: { RETRY: 'loading' } } } });

这段代码展示了 XState v5 的多个关键能力:fromPromise把异步函数包装为可调用 Actor;invoke.src引用 setup 中声明的 Actor;onDone/onError处理成功与失败;after实现延迟自动重试;assign更新 context。types.context声明让 context 获得完整类型推导。

再看 examples/timer/src/timerMachine.ts,它演示了fromCallback注册定时器 Actor、guard条件转换、always瞬时转换与全局事件:

export const timerMachine = setup({ actors: { ticks: fromCallback(({ sendBack }) => { const interval = setInterval(() => { sendBack({ type: 'TICK' }); }, 1000); return () => clearInterval(interval); }) } }).createMachine({ // types: 声明事件联合类型 context: { seconds: 0 }, initial: 'stopped', states: { stopped: { on: { start: { guard: ({ context }) => context.seconds > 0, // 条件转换 target: 'running' }, minute: { actions: assign({ seconds: ({ context }) => context.seconds + 60 }) } } }, running: { invoke: { src: 'ticks' }, on: { stop: 'stopped', TICK: { actions: assign({ seconds: ({ context }) => context.seconds - 1 }) } }, always: { guard: ({ context }) => context.seconds === 0, // 瞬时转换 target: 'stopped' } } } });

核心包导出的 API 还包括and/or/not/stateIn组合守卫、getNextSnapshot、waitFor、toPromise、SimulatedClock、mapState等(见 packages/core/src/index.ts)。

@xstate/store:轻量状态管理

不是每个应用都需要状态机的全部能力。@xstate/store是一个独立、极小的事件驱动 store,TypeScript 推导一流,风格接近 Redux/Zustand 但样板代码更少。可以单独使用,也可以在逻辑复杂后升级到完整的状态机。

npm install @xstate/store
import { createStore } from '@xstate/store'; const donutStore = createStore({ context: { donuts: 0, favoriteFlavor: 'chocolate' }, on: { addDonut: (context) => ({ ...context, donuts: context.donuts + 1 }), changeFlavor: (context, event: { flavor: string }) => ({ ...context, favoriteFlavor: event.flavor }), eatAllDonuts: (context) => ({ ...context, donuts: 0 }) } }); donutStore.subscribe((snapshot) => { console.log(snapshot.context); }); donutStore.send({ type: 'addDonut' }); // => { donuts: 1, favoriteFlavor: 'chocolate' } donutStore.send({ type: 'changeFlavor', flavor: 'strawberry' }); // => { donuts: 1, favoriteFlavor: 'strawberry' }

@xstate/store的完整文档(含 React/Solid 绑定、selector 等)见 packages/xstate-store/README.md,测试与实现位于 packages/xstate-store/src/alien.ts 与 packages/xstate-store/test。

状态机的四种核心形态

README 用"代码 + Statechart 可视化"成对呈现了四种形态,这是 XState 建模的基本功。

1. 有限状态机(Finite State Machine)

三个状态首尾相接,每次TIMER事件推进一档:

import { createMachine, createActor } from 'xstate'; const lightMachine = createMachine({ id: 'light', initial: 'green', states: { green: { on: { TIMER: 'yellow' } }, yellow: { on: { TIMER: 'red' } }, red: { on: { TIMER: 'green' } } } }); const actor = createActor(lightMachine); actor.subscribe((state) => console.log(state.value)); actor.start(); // logs 'green' actor.send({ type: 'TIMER' }); // logs 'yellow'

注意这里的on: { TIMER: 'yellow' }是{ target: 'yellow' }的简写语法。

2. 层级(嵌套)状态机(Hierarchical / Nested)

状态内部还可以嵌套子状态。下面例子把行人信号灯嵌套在red中:

import { createMachine, createActor } from 'xstate'; const pedestrianStates = { initial: 'walk', states: { walk: { on: { PED_TIMER: 'wait' } }, wait: { on: { PED_TIMER: 'stop' } }, stop: {} } }; const lightMachine = createMachine({ id: 'light', initial: 'green', states: { green: { on: { TIMER: 'yellow' } }, yellow: { on: { TIMER: 'red' } }, red: { on: { TIMER: 'green' }, ...pedestrianStates } } }); const actor = createActor(lightMachine); actor.subscribe((state) => console.log(state.value)); actor.start(); // logs 'green' actor.send({ type: 'TIMER' }); // logs 'yellow' actor.send({ type: 'TIMER' }); // logs { red: 'walk' } actor.send({ type: 'PED_TIMER' }); // logs { red: 'wait' }

进入嵌套状态后,state.value会呈现为对象形态(如{ red: 'walk' }),这正是resolveStateValue等状态解析逻辑(stateUtils.ts)的作用结果。

3. 并行状态机(Parallel State Machines)

把机器声明为type: 'parallel',多个区域(region)同时独立活动,任一区域的转换不影响其他区域:

import { createMachine, createActor } from 'xstate'; const wordMachine = createMachine({ id: 'word', type: 'parallel', states: { bold: { initial: 'off', states: { on: { on: { TOGGLE_BOLD: 'off' } }, off: { on: { TOGGLE_BOLD: 'on' } } } }, underline: { initial: 'off', states: { on: { on: { TOGGLE_UNDERLINE: 'off' } }, off: { on: { TOGGLE_UNDERLINE: 'on' } } } }, italics: { initial: 'off', states: { on: { on: { TOGGLE_ITALICS: 'off' } }, off: { on: { TOGGLE_ITALICS: 'on' } } } }, list: { initial: 'none', states: { none: { on: { BULLETS: 'bullets', NUMBERS: 'numbers' } }, bullets: { on: { NONE: 'none', NUMBERS: 'numbers' } }, numbers: { on: { BULLETS: 'bullets', NONE: 'none' } } } } } }); const actor = createActor(wordMachine); actor.subscribe((state) => console.log(state.value)); actor.start(); // logs { bold: 'off', italics: 'off', underline: 'off', list: 'none' } actor.send({ type: 'TOGGLE_BOLD' }); // logs { bold: 'on', italics: 'off', underline: 'off', list: 'none' } actor.send({ type: 'TOGGLE_ITALICS' }); // logs { bold: 'on', italics: 'on', underline: 'off', list: 'none' }

并行状态在 UI 中非常适合表达互不干扰的多个开关/选项组。

4. 历史状态(History States)

type: 'history'的状态用于"记住"离开前的子状态,返回时直接恢复到记忆中的位置:

import { createMachine, createActor } from 'xstate'; const paymentMachine = createMachine({ id: 'payment', initial: 'method', states: { method: { initial: 'cash', states: { cash: { on: { SWITCH_CHECK: 'check' } }, check: { on: { SWITCH_CASH: 'cash' } }, hist: { type: 'history' } }, on: { NEXT: 'review' } }, review: { on: { PREVIOUS: 'method.hist' } } } }); const actor = createActor(paymentMachine); actor.subscribe((state) => console.log(state.value)); actor.start(); // logs { value: { method: 'cash' } } actor.send({ type: 'SWITCH_CHECK' }); // logs { value: { method: 'check' } } actor.send({ type: 'NEXT' }); // logs { value: 'review' } actor.send({ type: 'PREVIOUS' }); // logs { value: { method: 'check' } }

注意PREVIOUS: 'method.hist'使用点路径定位到嵌套历史状态,返回后恢复的是check而非初始的cash。

仓库中的更多实战示例

本仓库 examples 目录包含大量可直接运行的示例,覆盖各种技术栈与业务场景,可作为学习与脚手架参考:

  • 框架集成:7guis-counter-react、7guis-temperature-react、friends-list-react、snake-react、tic-tac-toe-react、todomvc-react、tiles、timer等 React 示例,以及7guis-1-counter-vue、7guis-2-temperature-vue等 Vue 示例;
  • 纯逻辑/后端:express-workflow(Express 工作流)、mongodb-credit-check-api(MongoDB 信用核查)、mongodb-persisted-state(MongoDB 持久化状态恢复)、fetch(异步请求状态机)、counter、stopwatch、toggle;
  • 工作流编排:workflow-*系列展示了事件驱动编排、并行子流程、异步子流程、超时截止、云事件发送等大量后端编排模式。

以 examples/friends-list-react/src/friendsMachine.ts 为代表的 UI 示例展示了机器与组件的集成方式:组件通过useMachine/useActorRef(对应 packages/xstate-react)订阅快照并把事件send回机器。

SemVer 政策与升级注意事项

XState 对公开契约非常谨慎,README 明确了以下承诺:

  • 运行时 API:不会在 minor 或 patch 版本中引入破坏性变更;
  • 行为变更:由于 XState 会执行大量用户逻辑,任何行为变化都可能被视为破坏性变更,团队会谨慎评估,但保留在 minor 版本中做某些行为调整的权利,升级前务必阅读 release notes;
  • TypeScript 类型:团队保留在 minor 版本中调整类型声明或放弃对旧版 TypeScript 支持的权利——TypeScript 本身演进迅速,类型推导也在持续改进;
  • 包依赖:XState 家族大部分包声明对xstate的 peer dependency,新版本会始终把 peer dependency 范围调整到包含最新版xstate。你可以单独升级xstate而不升级@xstate/react;但升级@xstate/react时,强烈建议同步升级xstate。

当前仓库核心包版本为5.32.6(见 packages/core/package.json),并提供了xstate/guards、xstate/actions、xstate/actors、xstate/graph、xstate/dev等子路径导出,方便按需引入。

总结

从 README 出发,结合源码与示例,可以梳理出 XState v5 的完整使用路径:先用@xstate/store处理简单状态,再用createMachine+setup建模复杂逻辑,用createActor实例化运行,通过start/send/subscribe驱动事件闭环;建模时优先考虑层级、并行、历史状态等 Statechart 结构,最后按 SemVer 政策谨慎规划升级。仓库中的 examples 目录是继续深入学习的绝佳资源,packages/xstate-react、packages/xstate-vue 等框架绑定则提供了与主流 UI 库的无缝集成。

  • 前端
  • 后端

【免费下载链接】xstate

State machines, statecharts, and actors for complex logic

项目地址:https://gitcode.com/gh_mirrors/xs/xstate
点击查看免费下载
上一篇:Feather网络请求优化:NimbleJSON服务与缓存策略
下一篇:企业级本地化平台深度解析:Tolgee自托管部署实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询