Qual è l'effettiva differenza tra redux e una macchina a stati (ad esempio xstate)?


93

Sto lavorando allo studio di un'applicazione front-end di media complessità. In questo momento è scritto in puro javascript, ha molti messaggi diversi basati su eventi che collegano poche parti principali di questa applicazione.

Abbiamo deciso di implementare una sorta di contenitore di stato per questa applicazione nell'ambito di un ulteriore refactoring. In precedenza ho avuto qualche esperienza con redux e ngrx store (che in realtà segue gli stessi principi).

Redux è un'opzione per noi, ma uno degli sviluppatori ha proposto di utilizzare una libreria basata sulla macchina a stati, in particolare la libreria xstate .

Non ho mai lavorato con xstate, quindi l'ho trovato interessante e ho iniziato a leggere la documentazione e guardare diversi esempi. Sembrava promettente e potente, ma a un certo punto ho capito che non vedo alcuna differenza significativa tra questo e redux.

Ho passato ore a cercare una risposta o qualsiasi altra informazione che confrontava xstate e redux. Non ho trovato alcuna informazione chiara, tranne alcuni articoli come "vai da redux a una macchina a stati" , o collegamenti a librerie incentrate sull'uso di redux e xstate insieme (abbastanza strano).

Se qualcuno può descrivere la differenza o dirmi quando gli sviluppatori dovrebbero scegliere xstate, sei il benvenuto.


3
I documenti ufficiali in realtà dicono che dovresti trattare i tuoi riduttori di redux come una macchina a stati redux.js.org/style-guide/…
Yannic Hamann

Penso che le librerie che hai menzionato potrebbero essere per l'utilizzo di xstate come sistema di gestione degli effetti (alternativo a thunk, saga, epic, ecc.)
Alfred Young,

Risposte:


205

Ho creato XState, ma non ho intenzione di dirti se usarne uno sull'altro; dipende dalla tua squadra. Cercherò invece di evidenziare alcune differenze chiave.

  • Redux è essenzialmente un contenitore di stato in cui gli eventi (chiamati azioni in Redux) vengono inviati a un riduttore che aggiorna lo stato.
  • XState è anche un contenitore di stati, ma separa lo stato finito (ad esempio "loading", "success") da "stato infinito", o contesto (ad esempio,items: [...] ).
  • Redux non determina come definire i riduttori. Sono funzioni semplici che restituiscono lo stato successivo dato lo stato corrente e l'evento (azione).
  • XState è un "riduttore con regole": definisci le transizioni legali tra stati finiti a causa di eventi e anche quali azioni dovrebbero essere eseguite in una transizione (o all'ingresso / uscita da uno stato)
  • Redux non ha un modo integrato per gestire gli effetti collaterali. Ci sono molte opzioni della community, come redux-thunk, redux-saga, ecc.
  • XState rende le azioni (effetti collaterali) dichiarative ed esplicite: fanno parte Statedell'oggetto restituito a ogni transizione (stato corrente + evento).
  • Redux attualmente non ha modo di visualizzare le transizioni tra stati, poiché non distingue tra stato finito e infinito.
  • XState ha un visualizzatore: https://statecharts.github.io/xstate-viz che è fattibile a causa della natura dichiarativa.
  • La logica / comportamento implicito rappresentato nei riduttori Redux non può essere serializzato in modo dichiarativo (ad esempio, in JSON)
  • Le definizioni della macchina di XState, che rappresentano logica / comportamento, possono essere serializzate in JSON e lette da JSON. Ciò rende il comportamento molto portabile e configurabile da strumenti esterni.
  • Redux non è strettamente una macchina a stati.
  • XState aderisce strettamente alla specifica SCXML del W3C: https://www.w3.org/TR/scxml/
  • Redux si affida allo sviluppatore per prevenire manualmente gli stati impossibili.
  • XState utilizza i grafici di stato per definire in modo naturale i confini per la gestione degli eventi, il che impedisce stati impossibili e può essere analizzato staticamente.
  • Redux incoraggia l'uso di un unico negozio atomico "globale".
  • XState incoraggia l'uso di un approccio simile a un modello di attore, in cui possono esserci molte istanze gerarchiche di grafici / "servizi" che comunicano tra loro.

Aggiungerò altre differenze chiave ai documenti questa settimana.


6
Finalmente qualcuno che usa FSM e SCXML per lo sviluppo frontale ... amico, mi hai salvato la vita, vado a studiare la tua libreria. Non mi piace il redux per alcune ragioni (prima confonde i termini di evento e azione) e in secondo luogo "modella" stati complessi con milioni di flag (verbose e imho non corretti).
Carlos Verdes

1
@ Mike76 XState si integra con gli strumenti di sviluppo Redux.
David Khourshid

Grazie per il suggerimento, lo esaminerò.
Mike76

1
Ora ho provato XState + Redux DevTools. Funziona abbastanza bene, ma alcune funzionalità sembrano mancare. Ad esempio, XState + Redux DevTools non supporta funzionalità come "replay dello stato" in cui viene riprodotta una sequenza di stati precedenti. Ciò è dovuto a limitazioni di implementazione?
Mike76

21

La macchina a stati non dice (forza) di avere un flusso di dati unidirezionale. Non ha nulla a che fare con il flusso di dati. Si tratta più di limitare i cambiamenti di stato e di transizioni di stato . Quindi, generalmente solo alcune parti dell'applicazione sarebbero progettate con macchine a stati, solo e solo se è necessario vincolare / vietare alcuni cambiamenti di stato e si è interessati alle transizioni.

Fai attenzione che con le macchine a stati, se per qualche motivo (dipendenza API esterna ecc ...), c'è la possibilità che l'app possa bloccarsi in uno stato in cui non può passare a un altro stato a causa di vincoli, devi risolverlo.

Ma se sei interessato solo allo stato dell'ultima app stessa, invece delle transizioni di stato , e i vincoli di stato non contano, allora è meglio non usare la macchina a stati e aggiornare direttamente lo stato stesso ( puoi comunque racchiudere lo stato in un aggiornamento della classe Singleton tramite Classi di azione ).


D'altra parte, Redux è un framework di architettura unidirezionale . Le architetture unidirezionali impongono di avere un'unica direzione del flusso di dati. In Redux, inizia con User->View->(Action)->Store->Reducer->(Middleware)->Store->(State)->View. Come per le macchine a stati, puoi attivare effetti collaterali con i middleware in Redux. Puoi limitare / vietare le transizioni di stato, se lo desideri. Diversamente da State Machine , Redux impone un flusso di dati unidirezionale, puro ! funzioni di riduzione, oggetti di stato immutabili, singolo stato osservabile dell'app.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.