Skip to content

Systems

演员系统是可以相互通信的演员集合。演员可以调用/生成其他演员,从而形成属于同一系统的自然层次结构。

在 XState 中,系统是从根演员隐式创建的,即从 createActor(machine).start() 返回的演员。系统可以从演员的 actor.system 属性以及从状态机动作中解构的 { system } 属性访问:

import { createMachine, createActor } from 'xstate';

const machine = createMachine({
entry: ({ system }) => {
// ...
},
});

const actor = createActor(machine).start();
actor.system;

系统的根也可以在 createActor(...) 函数中显式分配一个 systemId

import { createActor } from 'xstate';

const actor = createActor(machine, {
systemId: 'root-id',
});

actor.start();

这对于系统中的演员能够向根演员发送事件非常有用。

演员注册

演员可以注册到系统中,以便系统中的任何其他演员都可以获取其引用。

被调用的演员在 invoke 对象中使用系统范围的 systemId 注册:

import { createMachine, createActor, sendTo } from 'xstate';

const formMachine = createMachine({
// ...
on: {
submit: {
actions: sendTo(({ system }) => system.get('notifier'), {
type: 'notify',
message: 'Form submitted!',
}),
},
},
});

const feedbackMachine = createMachine({
invoke: {
systemId: 'formMachine',
src: formMachine,
},
// ...
states: {
// ...
form: {
invoke: formMachine,
},
},
});

const feedbackActor = createActor(feedbackMachine).start();

生成的演员在 spawn 函数的第二个参数中使用系统范围的 systemId 注册:

import { createMachine, createActor, assign } from 'xstate';

const todoMachine = createMachine({
// ...
});

const todosMachine = createMachine({
// ...
on: {
'todo.add': {
actions: assign({
todos: ({ context, spawn }) => {
const newTodo = spawn(todoMachine, {
systemId: `todo-${context.todos.length}`,
});

return context.todos.concat(newTodo);
},
}),
},
},
});

演员通信

您还可以使用 system.get('actorId') 从系统中引用特定演员:

停止系统

  • 从根演员停止:actor.stop()
  • 无法从子演员停止
    • 将记录警告

系统和 TypeScript

  • invoke.systemId
  • spawn(thing, { systemId })
  • system.get('actorId')
  • rootActor.stop()

系统备忘单

备忘单:演员系统

import { createMachine, createActor } from 'xstate';

const machine = createMachine({
entry: ({ system }) => {
// ...
},
});

const actor = createActor(machine).start();
actor.system;

备忘单:显式分配 systemId

import { createActor } from 'xstate';

const actor = createActor(machine, {
systemId: 'root-id',
});

actor.start();

备忘单:使用系统注册被调用的演员

import { createMachine, createActor, sendTo } from 'xstate';

const formMachine = createMachine({
// ...
on: {
submit: {
actions: sendTo(({ system }) => system.get('notifier'), {
type: 'notify',
message: 'Form submitted!',
}),
},
},
});

const feedbackMachine = createMachine({
invoke: {
systemId: 'formMachine',
src: formMachine,
},
// ...
states: {
// ...
form: {
invoke: formMachine,
},
},
});

const feedbackActor = createActor(feedbackMachine).start();

备忘单:使用系统注册生成的演员

import { createMachine, createActor, assign } from 'xstate';

const todoMachine = createMachine({
// ...
});

const todosMachine = createMachine({
// ...
on: {
'todo.add': {
actions: assign({
todos: ({ context, spawn }) => {
const newTodo = spawn(todoMachine, {
systemId: `todo-${context.todos.length}`,
});

return context.todos.concat(newTodo);
},
}),
},
},
});