分层状态节点 Hierarchical State Node

在状态图中,状态可以嵌套 在其他状态中 。 这些嵌套状态称为 复合状态。 要了解更多信息,请阅读状态图简介中的复合状态部分

API

以下示例是具有嵌套状态的交通灯状态机:

  1. const pedestrianStates = {
  2. initial: 'walk',
  3. states: {
  4. walk: {
  5. on: {
  6. PED_COUNTDOWN: { target: 'wait' }
  7. }
  8. },
  9. wait: {
  10. on: {
  11. PED_COUNTDOWN: { target: 'stop' }
  12. }
  13. },
  14. stop: {},
  15. blinking: {}
  16. }
  17. };
  18. const lightMachine = createMachine({
  19. key: 'light',
  20. initial: 'green',
  21. states: {
  22. green: {
  23. on: {
  24. TIMER: { target: 'yellow' }
  25. }
  26. },
  27. yellow: {
  28. on: {
  29. TIMER: { target: 'red' }
  30. }
  31. },
  32. red: {
  33. on: {
  34. TIMER: { target: 'green' }
  35. },
  36. ...pedestrianStates
  37. }
  38. },
  39. on: {
  40. POWER_OUTAGE: { target: '.red.blinking' },
  41. POWER_RESTORED: { target: '.red' }
  42. }
  43. });

'green''yellow' 状态是 简单的状态 ——它们没有子状态。 相比之下,'red' 状态是复合状态,因为它由 子状态pedestrianStates)组成。

初始状态

当进入复合状态时,它的初始状态也立即进入。 在以下交通灯状态机示例中:

  • 'red' 状态已进入
  • 由于 'red' 的初始状态为 'walk',因此最终进入 { red: 'walk' } 状态。
  1. console.log(lightMachine.transition('yellow', { type: 'TIMER' }).value);
  2. // => {
  3. // red: 'walk'
  4. // }

事件

当前状态不处理 event 时,该 event 将传播到其要处理的父状态。 在以下交通灯状态机示例中:

  • { red: 'stop' } 状态 处理'TIMER' 事件
  • 'TIMER' 事件被发送到处理该事件的 'red' 父状态。
  1. console.log(lightMachine.transition({ red: 'stop' }, { type: 'TIMER' }).value);
  2. // => 'green'

如果状态或其任何祖先(父)状态均未处理事件,则不会发生转换。 在 strict 模式下(在 状态机配置 中指定),这将引发错误。

  1. console.log(lightMachine.transition('green', { type: 'UNKNOWN' }).value);
  2. // => 'green'