Was ist ein tatsächlicher Unterschied zwischen Redux und einer Zustandsmaschine (z. B. xstate)?

85

Ich arbeite an der Untersuchung einer Front-End-Anwendung mittlerer Komplexität. In diesem Moment ist es in reinem Javascript geschrieben und enthält viele verschiedene ereignisbasierte Nachrichten, die einige Hauptteile dieser Anwendung verbinden.

Wir haben beschlossen, im Rahmen des weiteren Refactorings eine Art Statuscontainer für diese Anwendung zu implementieren. Zuvor hatte ich einige Erfahrungen mit Redux und Ngrx Store (was eigentlich den gleichen Prinzipien folgt).

Redux ist eine Option für uns, aber einer der Entwickler schlug vor, eine auf Zustandsmaschinen basierende Bibliothek zu verwenden, insbesondere die xstate-Bibliothek .

Ich habe noch nie mit xstate gearbeitet, fand es also interessant und fing an, Dokumentation zu lesen und mir verschiedene Beispiele anzusehen. Sah vielversprechend und kraftvoll aus, aber irgendwann verstand ich, dass ich keinen signifikanten Unterschied zwischen ihm und Redux sehe.

Ich habe stundenlang versucht, eine Antwort oder andere Informationen zu finden, die xstate und redux vergleichen. Ich habe keine klaren Informationen gefunden, außer einigen Artikeln wie "Von Redux zu einer Zustandsmaschine gelangen" oder Links zu Bibliotheken, die sich darauf konzentrieren, Redux und Xstate zusammen zu verwenden (ziemlich seltsam).

Wenn jemand den Unterschied beschreiben oder mir sagen kann, wann Entwickler xstate wählen sollten, sind Sie herzlich willkommen.

Artem Arkhipov
quelle
3
Die offiziellen Dokumente sagen tatsächlich, dass Sie Ihre Redux-Reduzierer als Zustandsmaschine reduzieren
Yannic Hamann
Ich denke, die Bibliotheken, die Sie erwähnen, könnten für die Verwendung von xstate als Effektmanagementsystem (Alternative zu Thunk, Saga, Epos usw.) sein
Alfred Young

Antworten:

188

Ich habe XState erstellt, aber ich werde Ihnen nicht sagen, ob Sie eines über dem anderen verwenden sollen. Das hängt von Ihrem Team ab. Stattdessen werde ich versuchen, einige wichtige Unterschiede hervorzuheben.

  • Redux ist im Wesentlichen ein Statuscontainer, in dem Ereignisse ( in Redux als Aktionen bezeichnet ) an einen Reduzierer gesendet werden, der den Status aktualisiert.
  • XState ist auch ein Zustand , Behälter, aber es trennt endlichen Zustand (zB "loading", "success") von „unendlich Zustand“ oder Kontext (zB items: [...]).
  • Redux schreibt nicht vor, wie Sie Ihre Reduzierungen definieren. Es handelt sich um einfache Funktionen, die angesichts des aktuellen Status und Ereignisses (Aktion) den nächsten Status zurückgeben.
  • XState ist ein "Reduzierer mit Regeln" - Sie definieren rechtliche Übergänge zwischen endlichen Zuständen aufgrund von Ereignissen und auch, welche Aktionen in einem Übergang (oder beim Betreten / Verlassen eines Zustands) ausgeführt werden sollen.
  • Redux verfügt nicht über eine integrierte Methode zur Behandlung von Nebenwirkungen. Es gibt viele Community-Optionen wie Redux-Thunk, Redux-Saga usw.
  • XState macht Aktionen (Nebenwirkungen) deklarativ und explizit - sie sind Teil des StateObjekts, das bei jedem Übergang zurückgegeben wird (aktueller Status + Ereignis).
  • Redux hat derzeit keine Möglichkeit, Übergänge zwischen Zuständen zu visualisieren, da es nicht zwischen endlichen und unendlichen Zuständen unterscheidet.
  • XState verfügt über einen Visualizer: https://statecharts.github.io/xstate-viz, der aufgrund des deklarativen Charakters möglich ist.
  • Die in Redux-Reduzierern dargestellte implizite Logik / das implizite Verhalten kann nicht deklarativ serialisiert werden (z. B. in JSON).
  • Die Maschinendefinitionen von XState, die Logik / Verhalten darstellen, können in JSON serialisiert und aus JSON gelesen werden. Dies macht das Verhalten sehr portabel und kann durch externe Tools konfiguriert werden.
  • Redux ist keine reine Zustandsmaschine.
  • XState hält sich strikt an die W3C SCXML-Spezifikation: https://www.w3.org/TR/scxml/
  • Redux verlässt sich darauf, dass der Entwickler unmögliche Zustände manuell verhindert.
  • XState verwendet Zustandsdiagramme, um auf natürliche Weise Grenzen für die Behandlung von Ereignissen zu definieren. Dies verhindert unmögliche Zustände und kann statisch analysiert werden.
  • Redux empfiehlt die Verwendung eines einzigen "globalen" Atomspeichers.
  • XState empfiehlt die Verwendung eines actor-model-ähnlichen Ansatzes, bei dem es viele hierarchische Statechart- / "Service" -Instanzen geben kann, die miteinander kommunizieren.

Ich werde diese Woche weitere wichtige Unterschiede zu den Dokumenten hinzufügen.

David Khourshid
quelle
5
Endlich jemand, der FSM und SCXML für die Frontentwicklung verwendet ... Mann, du hast mir das Leben gerettet, ich werde deine Bibliothek studieren. Ich mag Redux aus bestimmten Gründen nicht (erstens verwechselt es Ereignis- und Aktionsbegriffe) und zweitens "modelliert" es komplexe Zustände mit Millionen Flags (ausführlich und imho falsch).
Carlos Verdes
1
@ Mike76 XState lässt sich in Redux-Entwicklungstools integrieren.
David Khourshid
Danke für den Hinweis, ich werde das untersuchen.
Mike76
1
Ich habe jetzt XState + Redux DevTools ausprobiert. Es funktioniert ganz gut, aber einige Funktionen scheinen zu fehlen. Beispielsweise unterstützt XState + Redux DevTools keine Funktionen wie "Statuswiedergabe", bei der eine Folge vorheriger Status wiedergegeben wird. Liegt dies an Implementierungsbeschränkungen?
Mike76
20

Die Zustandsmaschine weist Sie nicht an, einen unidirektionalen Datenfluss zu erzwingen. Es hat nichts mit Datenfluss zu tun. Es geht mehr darum , Zustandsänderungen und Zustandsübergänge einzuschränken . Daher werden im Allgemeinen nur einige Teile der Anwendung mit Zustandsautomaten entworfen, und zwar nur dann, wenn Sie einige Zustandsänderungen einschränken / verbieten müssen und an Übergängen interessiert sind .

Beachten Sie, dass bei Zustandsautomaten, wenn aus irgendeinem Grund (externe API-Abhängigkeit usw.) die Möglichkeit besteht, dass die App in einem Zustand gesperrt wird, in dem sie aufgrund von Einschränkungen nicht in einen anderen Zustand übergehen kann, Sie sie lösen müssen.

Aber wenn Sie nur in letzten App Staat selbst, statt interessierte Zustandsübergänge und Zustandsbeschränkungen keine Rolle, dann besser nicht Zustandsmaschine verwenden und direkt seine Aktualisierung Zustand selbst ( Sie noch Zustand in einer Singleton - Klasse Update wickeln können durch Aktionsklassen ).


Auf der anderen Seite, Redux ist unidirektional Architektur - Framework . Unidirektionale Architekturen erzwingen eine einheitliche Richtung des Datenflusses. In Redux beginnt es mit User->View->(Action)->Store->Reducer->(Middleware)->Store->(State)->View. Wie bei State Machines können Sie mit Middlewares in Redux Nebenwirkungen auslösen. Sie können Statusübergänge einschränken / verbieten, wenn Sie möchten. Im Gegensatz zu State Machine erzwingt Redux einen unidirektionalen Datenfluss, pur ! Reduzierfunktionen, unveränderliche Statusobjekte, einzelner beobachtbarer App-Status.

Jemshit Iskenderov
quelle