# 机器

¥Machines

这些 XState v4 文档不再维护

XState v5 现已推出!阅读有关 XState v5 的更多信息 (opens new window)

¥XState v5 is out now! Read more about XState v5 (opens new window)

🆕 在我们的新文档中查找有关 使用 XState 创建机器 (opens new window) 的更多信息。

¥🆕 Find more about creating machines using XState (opens new window) in our new docs.

状态机是一组有限的状态,可以根据事件确定性地相互转换。要了解更多信息,请阅读我们的 状态图简介

¥A state machine is a finite set of states that can transition to each other deterministically due to events. To learn more, read our introduction to statecharts.

# 配置

¥Configuration

状态机和状态图都是使用 createMachine() 工厂函数定义的:

¥State machines and statecharts alike are defined using the createMachine() factory function:

import { createMachine } from 'xstate';

const lightMachine = createMachine({
  // Machine identifier
  id: 'light',

  // Initial state
  initial: 'green',

  // Local context for entire machine
  context: {
    elapsed: 0,
    direction: 'east'
  },

  // State definitions
  states: {
    green: {
      /* ... */
    },
    yellow: {
      /* ... */
    },
    red: {
      /* ... */
    }
  }
});

机器配置与 状态节点配置 相同,但添加了上下文属性:

¥The machine config is the same as the state node config, with the addition of the context property:

  • context - 代表机器所有嵌套状态的本地 "扩展状态"。详细信息请参见 上下文文档

    ¥context - represents the local "extended state" for all of the machine's nested states. See the docs for context for more details.

# 选项

¥Options

actionsdelaysguardsservices 的实现可以在机器配置中作为字符串引用,然后在 createMachine() 的第二个参数中指定为对象:

¥Implementations for actions, delays, guards, and services can be referenced in the machine config as a string, and then specified as an object in the 2nd argument to createMachine():

const lightMachine = createMachine(
  {
    id: 'light',
    initial: 'green',
    states: {
      green: {
        // action referenced via string
        entry: 'alertGreen'
      }
    }
  },
  {
    actions: {
      // action implementation
      alertGreen: (context, event) => {
        alert('Green!');
      }
    },
    delays: {
      /* ... */
    },
    guards: {
      /* ... */
    },
    services: {
      /* ... */
    }
  }
);

该对象有 5 个可选属性:

¥This object has 5 optional properties:

  • actions - 动作名称与其实现的映射

    ¥actions - the mapping of action names to their implementation

  • delays - 延迟名称与其实现的映射

    ¥delays - the mapping of delay names to their implementation

  • guards - 转换守卫 (cond) 名称与其实现的映射

    ¥guards - the mapping of transition guard (cond) names to their implementation

  • services - 调用的服务(src)名称到其实现的映射

    ¥services - the mapping of invoked service (src) names to their implementation

  • activities(已弃用) - 活动名称与其实现的映射

    ¥activities (deprecated) - the mapping of activity names to their implementation

# 扩展机器

¥Extending Machines

现有机器可以使用 .withConfig() 进行扩展,它采用与上面相同的对象结构:

¥Existing machines can be extended using .withConfig(), which takes the same object structure as above:

const lightMachine = // (same as above example)

const noAlertLightMachine = lightMachine.withConfig({
  actions: {
    alertGreen: (context, event) => {
      console.log('green');
    }
  }
});

# 初始上下文

¥Initial Context

如第一个示例所示,context 直接在配置本身中定义。如果你想使用不同的初始 context 扩展现有机器,你可以使用 .withContext() 并传入自定义 context

¥As shown in the first example, the context is defined directly in the configuration itself. If you want to extend an existing machine with a different initial context, you can use .withContext() and pass in the custom context:

const lightMachine = // (same as first example)

const testLightMachine = lightMachine.withContext({
  elapsed: 1000,
  direction: 'north'
});

警告

这不会对原始 context 进行浅层合并,而是将原始 context 替换为提供给 .withContext(...)context。你仍然可以通过引用 machine.context 手动设置 "merge" 上下文:

¥This will not do a shallow merge of the original context, and will instead replace the original context with the context provided to .withContext(...). You can still "merge" contexts manually, by referencing machine.context:

const testLightMachine = lightMachine.withContext({
  // merge with original context
  ...lightMachine.context,
  elapsed: 1000
});