如果你发送一个在 React Xstate 中不存在的事件会发生什么?

IT技术 reactjs state state-management xstate
2021-05-18 05:15:32

以这个有限状态机为例:

{
  initial: "foo",
  states: {
    foo: {
      on: { BAR: "bar" }
    },
    bar: {
      on: { FOO: "foo" }
    }
  }
}

在我的组件中,我这样做:

import { useMachine } from "@xstate/react";

export default function() {
  const [current, send] = useMachine(machine);

  useEffect(() => {
    send("BAR");
  }, []);

  return (
    <>
      Hello World  
    </>
  );
}

这是完全有效的代码,机器将切换到“bar”状态。现在,如果我这样做会怎样?

useEffect(() => {
  send("QUX");
}, []);

QUX事件未在机器中定义。

2个回答

在这种情况下,状态机解释器应该忽略计划外的事件。这就是状态机的工作原理。如果找不到事件,则不会进行转换评估。

根据状态机定义

状态机是一组有限的状态,可以由于事件而确定性地相互转换

计划的事件导致计划的转换(如果守卫通过)。

考虑到如果您处于foo状态,事件"QUX"定义在状态层次结构的上层,解释器会找到它并评估在那里定义的转换。

在分层机器中,转换的优先级取决于它们在树中的深度;更深层次的转换更具体,因此具有更高的优先级。这与 DOM 事件的工作方式类似:如果单击按钮,则直接在按钮上的单击事件处理程序比窗口上的单击事件处理程序更具体。

有关此案例的更多信息,请参见此处,Xstate 文档的“转换”一章。

如果严格模式没有开启(默认没有开启),“StateNode”会根据事件尝试转换到合适的候选状态,没有找到,什么都不做。

这是确定是否出错的代码的链接,以及一个小片段:

if (this.strict) {
  if (!this.events.includes(_event.name) && !isBuiltInEvent(_event.name)) {
    throw new Error(
      `Machine '${this.id}' does not accept event '${_event.name}'`
    );
  }
}