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

时间:2019-02-01 15:41:22

标签: javascript redux state-machine xstate

我正在研究一个中等复杂性的前端应用程序。目前,它是用纯JavaScript编写的,它具有许多基于事件的消息,这些消息连接了该应用程序的主要部分。

我们认为很明显,在进一步重构的范围内,我们需要为此应用程序实现某种状态容器。以前,我对redux和ngrx store(实际上遵循相同的原理)有一些经验。

Redux是我们的一个选择,但是其中一位开发人员建议使用状态机,尤其是xstate library

我从来没有使用过这个东西,所以我发现它很有趣,并开始阅读文档并寻找不同的示例。看起来很有前途且功能强大,但在某些时候我了解到它与redux之间没有明显的区别。

我花了数小时试图找到答案,或者其他任何与比较xstate和redux有关的信息,或者一些“利弊”。不幸的是,我最终陷入了混乱。除了"get from redux to a state machine"之类的文章以外,我没有找到任何明确的信息,也没有指向专注于使用redux和xstate 一起的库的链接,这些最终使我分手。

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

谢谢。

3 个答案:

答案 0 :(得分:12)

我创建了XState,但是我不会告诉您是否要在另一个上使用它。这取决于您的团队。相反,我将着重强调一些关键差异。

  • Redux本质上是一个状态容器,事件(在Redux中称为 actions )被发送到reducer并更新状态。
  • XState还是状态容器,但它将有限状态(例如"loading""success")与“无限状态”或上下文(例如items: [...])分开。
  • Redux并没有规定如何定义减速器。它们是简单的函数,可以在给定当前状态和事件(动作)的情况下返回下一个状态。
  • XState是“带规则的约简器”-您可以定义由于事件导致的有限状态之间的合法转换,以及在转换(或从状态进入/退出)中应执行的操作
  • Redux并非 not 具有内置的处理副作用的方法。社区选项很多,例如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模型的方法,在该方法中,可以有许多相互通信的分层状态图/“服务”实例。

本周我将在文档中添加更多关键区别。

答案 1 :(得分:1)

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

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

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


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

答案 2 :(得分:1)

我的几点意见如下。

  • UI 状态和业务/后端状态在 redux 中耦合在一起。因此,ui 或业务状态的每次更新都会在 redux 存储中创建数据更新。
  • Xstate 将 UI 状态和后端状态分离。
  • 在 redux 中,所有节点都存在于根节点中。 Xstate 在独立引擎内分散和分发数据。
  • 应用程序只能在已定义的状态之间转换。所以任何错误或错误都可以在引擎本身中修复。
  • 内部状态由引擎本身在 Xstate 中管理。 Redux 将新状态表示为标志。
  • Renderer agonistic - 保持尽可能多的状态提升到机器中,如果我们需要,我们可以相对容易地切换渲染框架(例如从 react 到 vue)。
  • Contexts 提供了具体的类来向外界呈现单一接口。