redux和状态机之间的实际差异是什么(例如xstate)?

Art*_*pov 35 javascript state-machine redux xstate

我正在研究一种中等复杂度的前端应用程序.此时它是用纯JavaScript编写的,它有很多不同的基于事件的消息,连接了这个应用程序的几个主要部分.

我们决定显然我们需要在进一步重构的范围内为这个应用程序实现某种状态容器.以前我有一些使用redux和ngrx存储的经验(实际上遵循相同的原则).

Redux是我们的选择,但其中一个开发人员建议使用状态机,特别是xstate库.

我从来没有使用过这个东西,所以我发现它很有趣,并开始阅读文档并查看不同的例子.看起来很有前途和强大,但在某些时候我明白我没有看到它和redux之间的显着差异.

我花了好几个小时试图找到答案,或者与比较xstate和redux或者一些"利弊"相关的任何其他信息.不幸的是,我最终弄得一团糟.我没有找到任何明确的信息,除了像一些文章"从终极版以状态机得到",或指向集中于使用终极版和XSTATE库一起,并且终于突破了我.

如果有人可以描述差异或告诉我何时开发人员应该选择xstate - 欢迎你.

谢谢.

Dav*_*hid 59

我创建了XState,但我不打算告诉你是否使用一个而不是另一个; 这取决于你的团队.相反,我会尝试突出一些关键的差异.

  • Redux本质上是一个状态容器,其中事件(在Redux中称为操作)被发送到更新状态的reducer.
  • XState也是一个状态容器,但它将有限状态(例如"loading","success")与"无限状态"或上下文(例如items: [...])分开.
  • Redux并未规定您如何定义减速器.它们是普通函数,在给定当前状态和事件(操作)的情况下返回下一个状态.
  • XState是一个"带规则的简化器" - 您可以定义由于事件而导致的有限状态之间的合法转换,以及应该在转换中(或从状态进入/退出时)执行哪些操作
  • 终极版并没有有一个内置的方式来处理副作用.有许多社区选项,如redux-thunk,redux-saga等.
  • XState使动作(副作用)声明和显式 - 它们是State每次转换(当前状态+事件)时返回的对象的一部分.
  • Redux目前无法可视化状态之间的转换,因为它无法区分有限状态和无限状态.
  • XState有一个可视化器:https://statecharts.github.io/xstate-viz ,由于声明性质,这是可行的.
  • Redux reducer中表示的隐式逻辑/行为无法以声明方式序列化(例如,在JSON中)
  • XState的机器定义代表逻辑/行为,可以序列化为JSON,并从JSON读取.这使得行为非常便携并且可以通过外部工具进行配置.
  • Redux不是严格意义上的状态机.
  • XState严格遵守W3C SCXML规范:https://www.w3.org/TR/scxml/
  • Redux依靠开发人员手动防止不可能的状态.
  • XState使用状态图自然地定义处理事件的边界,这可以防止不可能的状态并且可以静态分析.
  • Redux鼓励使用单一的"全球"原子商店.
  • XState鼓励使用类似Actor模型的方法,其中可以存在许多彼此通信的分层状态图/"服务"实例.

我将在本周为文档添加更多关键差异.

  • 终于有人使用 FSM 和 SCXML 进行前端开发了...伙计,你救了我的命,我要研究你的库。由于某些原因,我不喜欢 redux(首先它混淆了事件和操作术语),其次它用百万个标志“模型”复杂状态(冗长且恕我直言不正确)。 (14认同)
  • @Mike76 XState 与 Redux 开发工具集成。 (2认同)

Jem*_*rov 6

状态机不会告诉(强制)您具有单向数据流。它与数据流无关。它更多是关于约束状态变化状态转换。因此,通常只有在您需要约束/禁止某些状态更改并且您转换感兴趣时,才仅使用状态机来设计应用程序的某些部分。

请注意,在状态机的情况下,如果由于某种原因(外部API依赖性等),应用可能会因为某种限制而被锁定在无法转换为另一状态的状态,则必须解决该问题。

但是,如果您只对上一个应用程序状态本身感兴趣,而不是对状态转换不感兴趣,并且状态约束并不重要,那么最好不要使用状态机,而直接更新状态本身(您仍然可以通过以下方式将状态包装在Singleton类更新中:动作类)。


另一方面,Redux单向架构框架。单向体系结构强制您具有单一方向的数据流。在Redux中,它以开始User->View->(Action)->Store->Reducer->(Middleware)->Store->(State)->View。像状态机一样,您可以在Redux中使用中间件来触发副作用。如果需要,您可以约束/禁止状态转换。与状态机不同,Redux强制单向数据流,纯粹!减速器功能,不可变状态对象,单个可观察的应用程序状态。