States
states 是整个状态机的核心,用于声明「有哪些状态」以及「每个状态能做什么」。
ts
end: {
description: '结束',
type: 'final',
meta: {
index: 6,
component: markRaw(END),
title: '一审结束',
disabled: true,
},
},每个 states.xxx 都是一个 状态节点配置对象:
tags
tag 是你给“状态节点”贴的语义标签,和层级、名字无关,只表达“这个状态属于哪一类”。
ts
const feedbackMachine = createMachine({
// ...
states: {
submitting: {
tags: ['loading'],
// ...
},
},
});
const feedbackActor = createActor(feedbackMachine).start();
const currentState = feedbackActor.getSnapshot();
const showLoadingSpinner = currentState.hasTag('loading');description
State descriptions(状态描述)。它不影响状态机运行,但对协作、可维护性、可视化非常重要。
State descriptions 是写给“人”看的说明文字,用来解释“这个状态是干嘛的”。用于文档、协作、可视化(尤其是 Stately Studio)。
meta
给 UI 用的状态信息
ts
meta: {
layout: 'fullscreen',
authRequired: true,
title: '提交成功',
}| 对比 | meta | context |
|---|---|---|
| 是否可变 | ❌ 不可变 | ✅ assign |
| 生命周期 | 定义期 | 运行期 |
| 作用 | 描述状态 | 保存数据 |
| 是否参与逻辑 | ❌ | ✅ |
| UI 配置 | ✅ 非常适合 | ❌ 不推荐 |
on
用于定义当前状态存在哪些事件,相当于声明了事件监听器,事件一般使用大写表示。具体参见:Transitions
on表示当状态处于当前节点,并且收到某个事件时,该怎么反应
invoke
invoke表示进入这个状态后,自动启动一个 Actor,并管理它的生命周期
ts
states: {
"Loading Move Destinations": {
description:
"Load data from the server based on the entity's id and type (project or machine). Result includes the entity's current location, and the list or tree of valid destination options to which the user may move that entity.",
invoke: {
src: "loadMoveData",
id: "loadMoveData",
onDone: [
{
target: "Destination Menu",
actions: "setDestinations",
},
],
onError: [
{
target: "Data Loading Error",
},
],
},
},
}entry
进入状态时执行的Action
ts
loading: {
entry: 'startLoading',
exit: 'stopLoading'
}exit
离开当前状态时执行的Action
always
无事件的自动迁移
type
定义当前事件的特殊类型
ts
final | parallel | history普通状态
不声明type的值的状态就是普通状态
final
一旦进入该状态
当前这个 state node 所在的 machine / 子 machine 就结束
snapshot.status === 'done'parallel
并行状态:同一时间同时处于多个子状态
ts
working: {
type: 'parallel',
states: {
form: {},
attachment: {}
}
}snapshot.value:
ts
{
working: {
form: 'idle',
attachment: 'uploading'
}
}history
记住上一次的子状态
ts
import { createMachine } from 'xstate'
const panelMachine = createMachine({
id: 'panel',
initial: 'panel',
states: {
panel: {
initial: 'list',
states: {
list: {
on: { VIEW: 'detail' }
},
detail: {
on: { BACK: 'list' }
},
history: {
type: 'history'//可以记住上次的状态是list还是detail
}
},
on: {
LEAVE: 'other'
}
},
other: {
on: {
ENTER: 'panel.history'
}
}
}
})结果:
ts
panel.list
→ VIEW → panel.detail
→ LEAVE → other
→ ENTER → panel.detail ✅(自动回到 detail)states
状态还可以嵌套声明子状态:
ts
trial: {
description: '开庭',
initial: 'notice',
meta: {
index: 3,
component: markRaw(Step3),
title: '开庭',
},
states: {
notice: {
meta: { index: 3.1, title: '开庭' },
description: '收到开庭通知',
on: {
NEXT: {
target: 'wait',
actions: assign({
progressId: 17,
}),
},
},
},
wait: {
meta: { index: 3.2, title: '等待开庭', disabled: true },
description: '开庭中',
on: {
NEXT: {
target: 'end',
},
},
},
// 后端生成的记录nextKey:end
end: {
meta: { index: 3.3, title: '庭审结束' },
description: '庭审结束',
on: {
NEXT: {
target: '#firstTrial.trialMediation',
actions: 'resetProgressId',
},
},
},
},
},output
在 states 里,output 只能写在 type: 'final'` 的状态上。当状态机“走到这个 final 状态时”,产出的最终结果
- 静态值
ts
success: {
type: 'final',
output: {
result: 'ok'
}
}- 函数
ts
success: {
type: 'final',
output: ({ context }) => ({
result: 'ok'
})
}