¿Cuál es la diferencia real entre redux y una máquina de estado (por ejemplo, xstate)?

85

Estoy trabajando en la investigación de una aplicación front-end de complejidad media. En este momento está escrito en javascript puro, tiene muchos mensajes diferentes basados ​​en eventos que conectan algunas partes principales de esta aplicación.

Decidimos que necesitamos implementar algún tipo de contenedor de estado para esta aplicación en el ámbito de una mayor refactorización. Anteriormente tenía algo de experiencia con redux y ngrx store (que en realidad sigue los mismos principios).

Redux es una opción para nosotros, pero uno de los desarrolladores propuso usar una biblioteca basada en máquina de estado, en particular la biblioteca xstate .

Nunca he trabajado con xstate, así que lo encontré interesante y comencé a leer documentación y buscar diferentes ejemplos. Parecía prometedor y poderoso, pero en algún momento entendí que no veo ninguna diferencia significativa entre él y redux.

Pasé horas tratando de encontrar una respuesta, o cualquier otra información comparando xstate y redux. No encontré ninguna información clara, excepto algunos artículos como "get from redux to a state machine" , o enlaces a bibliotecas enfocadas en usar redux y xstate juntos (bastante extraño).

Si alguien puede describir la diferencia o decirme cuándo los desarrolladores deben elegir xstate, puede hacerlo.

Artem Arkhipov
fuente
3
Los documentos oficiales en realidad dicen que debe tratar sus reductores redux como una máquina de estado redux.js.org/style-guide/…
Yannic Hamann
Creo que las bibliotecas que mencionas podrían ser para usar xstate como un sistema de administración de efectos (alternativa a thunk, saga, epic, etc.)
Alfred Young

Respuestas:

188

Creé XState, pero no voy a decirles si usar uno sobre el otro; eso depende de tu equipo. En cambio, intentaré resaltar algunas diferencias clave.

  • Redux es esencialmente un contenedor de estado donde los eventos (llamados acciones en Redux) se envían a un reductor que actualiza el estado.
  • XState es también un recipiente de estado, pero se separa de estado finito (por ejemplo, "loading", "success") de "estado infinito", o el contexto (por ejemplo, items: [...]).
  • Redux no dicta cómo define sus reductores. Son funciones simples que devuelven el siguiente estado dado el estado actual y el evento (acción).
  • XState es un "reductor con reglas": usted define las transiciones legales entre estados finitos debido a eventos y también qué acciones deben ejecutarse en una transición (o al entrar / salir de un estado)
  • Redux no tiene una forma incorporada de manejar los efectos secundarios. Hay muchas opciones de la comunidad, como redux-thunk, redux-saga, etc.
  • XState hace que las acciones (efectos secundarios) sean declarativas y explícitas: son parte del Stateobjeto que se devuelve en cada transición (estado actual + evento).
  • Actualmente, Redux no tiene forma de visualizar las transiciones entre estados, ya que no distingue entre estado finito e infinito.
  • XState tiene un visualizador: https://statecharts.github.io/xstate-viz que es factible debido a la naturaleza declarativa.
  • La lógica / comportamiento implícito representado en los reductores de Redux no se puede serializar de forma declarativa (por ejemplo, en JSON)
  • Las definiciones de máquina de XState, que representan la lógica / comportamiento, se pueden serializar en JSON y leer desde JSON. Esto hace que el comportamiento sea muy portátil y configurable por herramientas externas.
  • Redux no es estrictamente una máquina de estado.
  • XState se adhiere estrictamente a la especificación W3C SCXML: https://www.w3.org/TR/scxml/
  • Redux confía en el desarrollador para evitar manualmente estados imposibles.
  • XState usa diagramas de estado para definir naturalmente los límites para el manejo de eventos, lo que evita estados imposibles y se puede analizar estáticamente.
  • Redux fomenta el uso de una única tienda atómica "global".
  • XState fomenta el uso de un enfoque similar al modelo de actor, donde puede haber muchas instancias jerárquicas de "servicios" / gráficos de estado que se comunican entre sí.

Agregaré más diferencias clave a los documentos esta semana.

David Khourshid
fuente
5
Finalmente alguien usando FSM y SCXML para el desarrollo frontal ... hombre, me salvaste la vida, voy a estudiar tu biblioteca. No me gusta redux por algunas razones (primero confunde eventos y términos de acción) y en segundo lugar, "modela" estados complejos con millones de indicadores (detallado y en mi humilde opinión).
Carlos Verdes
1
@ Mike76 XState se integra con las herramientas de desarrollo de Redux.
David Khourshid
Gracias por la pista, lo investigaré.
Mike76
1
Ahora probé XState + Redux DevTools. Funciona bastante bien, pero parece que faltan algunas funciones. Por ejemplo, XState + Redux DevTools no admite funciones como "reproducción de estado", donde se reproduce una secuencia de estados anteriores. ¿Esto se debe a limitaciones de implementación?
Mike76
20

La máquina de estado no le dice (obliga) a tener un flujo de datos unidireccional. No tiene nada que ver con el flujo de datos. Se trata más de limitar los cambios de estado y de las transiciones de estado . Por lo tanto, generalmente solo algunas partes de la aplicación se diseñarían con máquinas de estado, solo y solo si necesita restringir / prohibir algunos cambios de estado y está interesado en las transiciones.

Tenga en cuenta que con las máquinas de estado, si por alguna razón (dependencia de API externa, etc.), existe la posibilidad de que la aplicación se bloquee en un estado en el que no pueda pasar a otro estado debido a restricciones, debe resolverlo.

Pero si solo está interesado en el estado de la última aplicación, en lugar de las transiciones de estado , y las restricciones de estado no importan, entonces es mejor que no use la máquina de estado y actualice directamente el estado en sí ( aún puede ajustar el estado en una actualización de clase Singleton a través de Clases de acción ).


Por otro lado, Redux es un marco de arquitectura unidireccional . Las arquitecturas unidireccionales le obligan a tener una sola dirección de flujo de datos. En Redux, comienza con User->View->(Action)->Store->Reducer->(Middleware)->Store->(State)->View. Al igual que State Machines, puede desencadenar efectos secundarios con Middlewares en Redux. Puede restringir / prohibir las transiciones de estado, si lo desea. A diferencia de State Machine , Redux fuerza un flujo de datos unidireccional, ¡ puro ! funciones reductoras, objetos de estado inmutables, estado de aplicación única observable.

Jemshit Iskenderov
fuente