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

Posted

技术标签:

【中文标题】如果你发送一个在 React Xstate 中不存在的事件会发生啥?【英文标题】:What happens if you send an event that doesn't exist in React Xstate?如果你发送一个在 React Xstate 中不存在的事件会发生什么? 【发布时间】:2020-03-13 05:37:02 【问题描述】:

以这个有限状态机为例:


  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事件。

【问题讨论】:

【参考方案1】:

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

根据状态机definition

状态机是一组有限的状态,它们可以根据事件确定地相互转换。

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

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

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

关于这个案例的更多信息可以在here,在 Xstate 文档的“转换”一章中找到。

【讨论】:

【参考方案2】:

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

Here is a link判断是否出错的代码,还有一个小sn -p:

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

【讨论】:

以上是关于如果你发送一个在 React Xstate 中不存在的事件会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 XState FSM 中使用外部数据

XState.js 如何将上下文发送到机器?

XState react - 跨多个组件共享机器实例

将事件发送到 XState 中的子服务数组

Discord react_add 在私信频道中不起作用

前端状态机系列:SCXML与XState对应关系