wake-up-neo.net

Warum Redux über Facebook Flux nutzen?

Ich habe gelesen diese Antwort , reduzierende Kesselplatte , einige GitHub-Beispiele angeschaut und sogar ein wenig Redux versucht (Apps zu erledigen).

Soweit ich weiß, bieten offizielle Redux Doc-Motivationen Profis im Vergleich zu traditionellen MVC-Architekturen. ABER es gibt keine Antwort auf die Frage:

Warum sollten Sie Redux über Facebook Flux verwenden?

Ist das nur eine Frage der Programmierstile: funktional oder nicht funktional? Oder ist die Frage in Fähigkeiten/Entwicklungswerkzeugen, die sich aus dem Redux-Ansatz ergeben? Vielleicht skalieren? Oder testen?

Habe ich recht, wenn ich sage, dass Redux ein Flussmittel für Menschen ist, die aus funktionalen Sprachen stammen?

Um diese Frage zu beantworten, können Sie die Komplexität der Implementierung Redux Motivationspunkte auf Fluss vs Redux vergleichen.

Hier sind die Motivationspunkte von offizielle Redux-Doc-Motivationen :

  1. Der Umgang mit optimistischen Updates ( hängt meines Wissens kaum vom fünften Punkt ab. Ist es schwierig, sie in Facebook Flux zu implementieren? )
  2. Rendering auf dem Server ( Facebook Flux kann das auch. Gibt es Vorteile im Vergleich zu Redux? )
  3. Abrufen von Daten vor dem Durchführen von Routenübergängen ( Warum kann dies in Facebook Flux nicht erreicht werden? Was sind die Vorteile?
  4. Hot Reload ( Mit React Hot Reload ist das möglich. Warum brauchen wir Redux? )
  5. Undo/Redo-Funktion
  6. Irgendwelche anderen Punkte? Wie anhaltender Zustand ...
1126
VB_

Redux-Autor hier!

Redux ist nicht das anders als Flux. Insgesamt hat es die gleiche Architektur, aber Redux ist in der Lage, einige Komplexitätsprobleme zu lösen, indem es eine funktionale Komposition verwendet, bei der Flux die Rückrufregistrierung verwendet.

Es gibt keinen grundsätzlichen Unterschied in Redux, aber ich finde, dass es bestimmte Abstraktionen einfacher oder zumindest möglich macht, diese in Flux zu implementieren, was schwierig oder unmöglich wäre.

Reduziererzusammensetzung

Nehmen wir zum Beispiel die Paginierung. Mein Flux + React Router-Beispiel behandelt die Paginierung, aber der Code dafür ist schrecklich. Einer der Gründe, warum es schrecklich ist, dass Flux die Wiederverwendung von Funktionen in Geschäften unnatürlich macht. Wenn zwei Geschäfte als Reaktion auf unterschiedliche Aktionen die Paginierung verarbeiten müssen, müssen sie Entweder müssen Sie von einem gemeinsamen Basisspeicher erben (schlecht, Sie sind an ein bestimmtes Design gebunden, wenn Sie die Vererbung verwenden), oder Sie rufen eine extern definierte Funktion in der Ereignisbehandlungsroutine auf, die auf irgendeine Weise im privaten Flux-Speicher ausgeführt werden muss Zustand. Das Ganze ist chaotisch (obwohl definitiv im Bereich möglich).

Auf der anderen Seite ist die Redux-Paginierung dank der Reduktionszusammensetzung natürlich. Es sind Reduzierungen ganz unten, also können Sie eine Reduzierungsfactory, die Paginierungsreduzierungen generiert und dann in Ihrem Reduzierungsbaum verwenden schreiben. Der Schlüssel, warum es so einfach ist, liegt darin, dass in Flux die Geschäfte flach sind, aber in Redux können Reduzierungen über die funktionale Komposition verschachtelt werden, genau wie React Komponenten verschachtelt werden können .

Dieses Muster ermöglicht auch wunderbare Funktionen wie No-User-Code Rückgängig/Wiederherstellen . Können Sie sich vorstellen, Undo/Redo in eine Flux-App einzubauen, die aus zwei Codezeilen besteht? Kaum. Bei Redux ist es wieder - dank des Reducer-Kompositionsmusters. Ich muss hervorheben, dass es nichts Neues gibt - dies ist das Muster, das in Elm Architecture , das selbst von Flux beeinflusst wurde, entwickelt und detailliert beschrieben wurde.

Server-Rendering

Die Leute haben auf dem Server mit Flux einwandfrei gerendert, aber da wir über 20 Flux-Bibliotheken verfügen, die jeweils versuchen, das Server-Rendering "einfacher" zu gestalten, hat Flux möglicherweise einige Probleme mit dem Server. Die Wahrheit ist, dass Facebook nicht viel Server-Rendering leistet, daher waren sie nicht sehr besorgt und verlassen sich auf das Ökosystem, um es einfacher zu machen.

Im traditionellen Flux sind Läden Singletons. Dies bedeutet, dass es schwierig ist, die Daten für verschiedene Anforderungen auf dem Server zu trennen. Nicht unmöglich, aber schwer. Aus diesem Grund empfehlen die meisten Flux-Bibliotheken (wie auch die neuen Flux Utils ) jetzt, Klassen anstelle von Singletons zu verwenden, damit Sie Stores auf Anfrage instanziieren können.

Es gibt immer noch die folgenden Probleme, die Sie in Flux lösen müssen (entweder selbst oder mithilfe Ihrer bevorzugten Flux-Bibliothek wie Flummox oder Alt ):

  • Wenn Stores Klassen sind, wie erstelle und lösche ich sie mit dem Dispatcher auf Anfrage? Wann melde ich Geschäfte an?
  • Wie kann ich die Daten aus den Geschäften hydratisieren und später auf dem Client rehydratisieren? Muss ich dafür spezielle Methoden implementieren?

Zwar haben Flux-Frameworks (nicht Vanilla Flux) Lösungen für diese Probleme, aber ich finde sie zu kompliziert. Beispiel: Flummox fordert Sie auf, serialize() und deserialize() in Ihren Filialen zu implementieren . Alt löst dieses Problem, indem Sie takeSnapshot() bereitstellen, das Ihren Status in einem JSON-Baum automatisch serialisiert.

Redux geht noch einen Schritt weiter: Da es nur ein einziges Geschäft gibt (das von vielen Reduzierern verwaltet wird), benötigen Sie keine spezielle API, um die (erneute) Flüssigkeitszufuhr zu verwalten. Sie müssen keine Geschäfte „spülen“ oder „hydratisieren“ - es gibt nur ein einziges Geschäft, und Sie können den aktuellen Status lesen oder ein neues Geschäft mit einem neuen Status erstellen. Jede Anforderung erhält eine separate Speicherinstanz. Weitere Informationen zum Rendern von Servern mit Redux.

Auch dies ist sowohl in Flux als auch in Redux möglich, aber Flux-Bibliotheken lösen dieses Problem, indem sie eine Menge APIs und Konventionen einführen, und Redux muss es nicht einmal lösen, da es dieses Problem in der nicht gibt erster platz dank konzeptioneller einfachheit.

Entwicklererfahrung

Ich hatte eigentlich nicht die Absicht, Redux zu einer beliebten Flux-Bibliothek zu machen - ich habe es geschrieben, als ich an meinem ReactEurope-Vortrag über heißes Nachladen mit Zeitreisen arbeitete. Ich hatte ein Hauptziel: es möglich zu machen, den Reduzierungscode im laufenden Betrieb zu ändern oder sogar die Vergangenheit zu ändern, indem Aktionen durchgestrichen werden, und zu sehen, wie der Zustand neu berechnet wird.

Ich habe keine einzige Flux-Bibliothek gesehen, die das kann. React Hot Loader lässt Sie dies auch nicht zu - tatsächlich bricht es, wenn Sie Flux-Stores bearbeiten, da es nicht weiß, was es mit ihnen tun soll.

Wenn Redux den Reduzierungscode neu laden muss, ruft es replaceReducer() auf und die App wird mit dem neuen Code ausgeführt. In Flux sind Daten und Funktionen in Flux-Stores verstrickt, sodass Sie nicht „nur die Funktionen ersetzen“ können. Außerdem müssten Sie die neuen Versionen irgendwie beim Dispatcher neu registrieren - etwas, das Redux noch nicht einmal hat.

Ökosystem

Redux hat ein reiches und schnell wachsendes Ökosystem . Dies liegt daran, dass einige Erweiterungspunkte wie Middleware bereitgestellt werden. Es wurde mit Anwendungsfällen wie Logging , Unterstützung für Promises , Observables , Routing , Immutability Dev Checks entwickelt. _, Persistenz , etc, im Auge behalten. Nicht alle davon werden sich als nützlich erweisen, aber es ist schön, Zugang zu einer Reihe von Werkzeugen zu haben, die einfach kombiniert werden können, um zusammenzuarbeiten.

Einfachheit

Redux bewahrt alle Vorteile von Flux (Aufzeichnung und Wiedergabe von Aktionen, unidirektionaler Datenfluss, abhängige Mutationen) und fügt neue Vorteile hinzu (einfaches Rückgängigmachen, Nachladen im laufenden Betrieb), ohne den Dispatcher einzuführen und die Registrierung vorzunehmen.

Es ist wichtig, es einfach zu halten, damit Sie bei der Implementierung übergeordneter Abstraktionen vernünftig bleiben.

Im Gegensatz zu den meisten Flux-Bibliotheken ist die Oberfläche der Redux-API winzig. Wenn Sie die Entwicklerwarnungen, -kommentare und -prüfungen entfernen, ist dies 99 Zeilen . Es gibt keinen schwierigen asynchronen Code zum Debuggen.

Sie können es tatsächlich lesen und alles von Redux verstehen.


Siehe auch meine Antwort auf die Nachteile der Verwendung von Redux im Vergleich zu Flux .

1959
Dan Abramov

In Quora sagt jemand :

Erstens ist es absolut möglich, Apps mit React ohne Flux zu schreiben.

Auch dieses visuelle Diagramm , das ich erstellt habe, um eine schnelle Ansicht von beiden zu zeigen, wahrscheinlich eine schnelle Antwort für die Leute, die das nicht lesen wollen ganze Erklärung: Flux vs Redux

Aber wenn Sie noch mehr wissen möchten, lesen Sie weiter.

Ich glaube, Sie sollten mit Pure React beginnen und dann Redux und Flux lernen. Nachdem Sie einige REAL-Erfahrungen mit React gesammelt haben, werden Sie sehen, ob Redux für Sie hilfreich ist oder nicht.

Vielleicht werden Sie das Gefühl haben, dass Redux genau für Ihre App geeignet ist, und vielleicht werden Sie feststellen, dass Redux versucht, ein Problem zu lösen, das Sie nicht wirklich haben.

Wenn Sie direkt mit Redux beginnen, werden Sie möglicherweise überentwickelten Code haben, der schwerer zu pflegen ist und noch mehr Fehler aufweist als ohne Redux.

From Redux docs :

Motivation
Da die Anforderungen an JavaScript-Anwendungen für einzelne Seiten immer komplizierter werden, muss unser Code mehr Status verwalten als jemals zuvor. Dieser Status kann Serverantworten und zwischengespeicherte Daten sowie lokal erstellte Daten enthalten, die noch nicht auf dem Server gespeichert wurden. Der Status der Benutzeroberfläche wird zunehmend komplexer, da aktive Routen, ausgewählte Registerkarten, Drehfelder, Paginierungssteuerelemente usw. verwaltet werden müssen.

Diesen sich ständig ändernden Zustand zu bewältigen ist schwierig. Wenn ein Modell ein anderes Modell aktualisieren kann, kann eine Ansicht ein Modell aktualisieren, wodurch ein anderes Modell aktualisiert wird. Dies kann wiederum dazu führen, dass eine andere Ansicht aktualisiert wird. Irgendwann verstehen Sie nicht mehr, was in Ihrer App passiert, da Sie die Kontrolle über das Wann, Warum und Wie des Status verloren haben. Wenn ein System undurchsichtig und nicht deterministisch ist, ist es schwierig, Fehler zu reproduzieren oder neue Funktionen hinzuzufügen.

Als ob dies nicht schon schlimm genug wäre, sollten Sie berücksichtigen, dass die neuen Anforderungen in der Front-End-Produktentwicklung immer häufiger werden. Von uns Entwicklern wird erwartet, dass wir optimistische Updates, serverseitiges Rendern, Abrufen von Daten vor dem Ausführen von Routenübergängen usw. durchführen. Wir versuchen, mit einer Komplexität umzugehen, mit der wir uns zuvor noch nie befasst hatten, und wir stellen unweigerlich die Frage: Ist es Zeit aufzugeben? Die Antwort ist nein.

Diese Komplexität ist schwierig zu handhaben, da wir zwei Konzepte vermischen, über die der menschliche Verstand nur schwer nachdenken kann: Mutation und Asynchronität. Ich nenne sie Mentos und Cola. Beide können im getrennten Zustand großartig sein, aber zusammen schaffen sie ein Durcheinander. Bibliotheken wie React versuchen, dieses Problem in der Ansichtsebene zu lösen, indem sie sowohl die Asynchronität als auch die direkte DOM-Manipulation entfernen. Die Verwaltung des Zustands Ihrer Daten bleibt Ihnen jedoch überlassen. Hier kommt Redux ins Spiel.

In Anlehnung an Flux, CQRS und Event Sourcing versucht Redux, Statusmutationen vorhersehbar zu machen, indem bestimmte Einschränkungen für die Art und Weise und den Zeitpunkt der Aktualisierung festgelegt werden. Diese Einschränkungen spiegeln sich in den drei Prinzipien von Redux wider.

Auch von Redux docs :

Kernkonzepte
Redux selbst ist sehr einfach.

Stellen Sie sich vor, der Status Ihrer App wird als einfaches Objekt beschrieben. Der Status einer Aufgaben-App könnte beispielsweise so aussehen:

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

Dieses Objekt ist wie ein "Modell", außer dass es keine Setter gibt. Auf diese Weise können verschiedene Teile des Codes den Status nicht willkürlich ändern, was zu schwer reproduzierbaren Fehlern führt.

Um etwas in dem Zustand zu ändern, müssen Sie eine Aktion auslösen. Eine Aktion ist ein einfaches JavaScript-Objekt (beachten Sie, dass wir keine Magie einführen?), Das beschreibt, was passiert ist. Hier sind einige Beispielaktionen:

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

Indem wir sicherstellen, dass jede Änderung als Aktion beschrieben wird, können wir genau nachvollziehen, was in der App vor sich geht. Wenn sich etwas geändert hat, wissen wir, warum es sich geändert hat. Aktionen sind wie Brotkrumen von dem, was passiert ist. Schließlich schreiben wir eine Funktion, die als Reduzierer bezeichnet wird, um Zustand und Handlungen miteinander zu verbinden. Auch hier ist nichts Magisches daran - es ist nur eine Funktion, die Status und Aktion als Argumente verwendet und den nächsten Status der App zurückgibt. Es wäre schwierig, eine solche Funktion für eine große App zu schreiben, daher schreiben wir kleinere Funktionen, die Teile des Staates verwalten:

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

Und wir schreiben einen weiteren Reduzierer, der den vollständigen Status unserer App verwaltet, indem wir diese beiden Reduzierer für die entsprechenden Statusschlüssel aufrufen:

function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  };
}

Dies ist im Grunde die ganze Idee von Redux. Beachten Sie, dass wir keine Redux-APIs verwendet haben. Es gibt einige Hilfsprogramme, die dieses Muster vereinfachen. Die Hauptidee ist jedoch, dass Sie beschreiben, wie Ihr Status als Reaktion auf Aktionsobjekte im Laufe der Zeit aktualisiert wird, und dass 90% des von Ihnen geschriebenen Codes nur einfaches JavaScript ohne Verwendung von Redux ist selbst, seine APIs oder irgendeine Magie.

101
Alireza

Beginnen Sie am besten mit dem Lesen dieses Beitrags von Dan Abramov, in dem er verschiedene Implementierungen von Flux und deren Kompromisse zu der Zeit behandelt, als er Redux schrieb: The Evolution of Flux Frameworks

Zweitens werden auf der Motivationsseite, auf die Sie verlinken, die Motivationen von Redux nicht so sehr erörtert wie die Motivationen hinter Flux (und React). Das Drei Prinzipien ist Redux-spezifischer, behandelt jedoch immer noch nicht die Implementierungsunterschiede zur Standard-Flux-Architektur.

Grundsätzlich verfügt Flux über mehrere Stores, die Statusänderungen als Reaktion auf Interaktionen zwischen Benutzeroberfläche und API mit Komponenten berechnen und diese Änderungen als Ereignisse senden, die von Komponenten abonniert werden können. In Redux gibt es nur einen Store, den jede Komponente abonniert. IMO sieht es zumindest so aus, als würde Redux den Datenfluss weiter vereinfachen und vereinheitlichen, indem der Datenfluss zurück zu den Komponenten vereinheitlicht (oder verringert, wie Redux sagen würde), wohingegen sich Flux darauf konzentriert, die andere Seite des Datenflusses zu vereinheitlichen Modell.

57
Hal

Ich bin ein Early Adopter und habe mithilfe der Facebook Flux-Bibliothek eine mittelgroße Einzelseitenanwendung implementiert.

Da ich etwas zu spät zum Gespräch komme, möchte ich nur darauf hinweisen, dass Facebook die Implementierung von Flux trotz meiner größten Hoffnungen als Proof of Concept zu betrachten scheint und es nie die Aufmerksamkeit erhalten hat, die es verdient.

Ich würde Sie ermutigen, damit zu spielen, da es mehr von der inneren Funktionsweise der Flux - Architektur enthüllt, was sehr lehrreich ist, aber gleichzeitig nicht viele der Vorteile bietet, die Bibliotheken wie Redux bieten (was nicht der Fall ist) das ist wichtig für kleine Projekte, wird aber für größere sehr wertvoll).

Wir haben beschlossen, dass wir in Zukunft zu Redux wechseln werden, und ich schlage vor, dass Sie dasselbe tun;)

27
Guy Nesher

Hier ist die einfache Erklärung von Redux über Flux. Redux hat keinen Dispatcher. Es basiert auf reinen Funktionen, die als Reduzierer bezeichnet werden. Es wird kein Dispatcher benötigt. Jede Aktion wird von einem oder mehreren Reduzierern ausgeführt, um den einzelnen Speicher zu aktualisieren. Da Daten unveränderlich sind, geben Reduzierer einen neuen aktualisierten Status zurück, der den Speicher aktualisiert enter image description here

Weitere Informationen Flux vs Redux

20
Prathap Kudupu

Ich habe ziemlich lange mit Flux gearbeitet und jetzt ziemlich lange mit Redux. Wie Dan betonte, sind beide Architekturen nicht so unterschiedlich. Die Sache ist, dass Redux die Dinge einfacher und sauberer macht. Es bringt Ihnen ein paar Dinge über Flux bei. Wie zum Beispiel ist Flux ein perfektes Beispiel für den Datenfluss in eine Richtung. Trennung von Anliegen, bei denen wir Daten haben, deren Manipulationen und Sichtebenen getrennt. In Redux haben wir die gleichen Dinge, aber wir lernen auch Unveränderlichkeit und reine Funktionen.

6
Krasimir

Von einem neuen React/Redux-Anwender, der Mitte 2018 von (einigen Jahren) ExtJS migriert ist:

Nachdem ich die Redux-Lernkurve rückwärts durchgegangen war, hatte ich die gleiche Frage und dachte, reines Fluxen wäre einfacher als OP.

Ich erkannte bald die Vorteile von Redux gegenüber Flux, wie in den obigen Antworten angegeben, und arbeitete es in meine erste App ein.

Während ich die Kesselplatte wieder in den Griff bekam, probierte ich einige der anderen State-Management-Bibliotheken aus. Das Beste, was ich fand, war Rematch .

Es war viel intuitiver als Vanilla Redux, es schneidet 90% des Boilerplates aus und 75% der Zeit, die ich mit Redux verbrachte (etwas) Ich denke, eine Bibliothek sollte das tun.) Ich konnte ein paar Unternehmensanwendungen sofort zum Laufen bringen.

Es wird auch mit demselben Redux-Tool ausgeführt. Dies ist ein guter Artikel , der einige der Vorteile abdeckt.

Also für alle anderen, die in diesem SO Beitrag nach "simpler redux" gesucht haben, empfehle ich, es als einfache Alternative zum Redux mit allen Vorteilen und 1/4 der Boilerplate auszuprobieren.

5
Geronimo

Nach diesem Artikel: https://medium.freecodecamp.org/a-realworld-comparison-of-front-end-frameworks-with-benchmarks-2019-update-4be0d3c78075

Verwenden Sie MobX besser zum Verwalten der Daten in Ihrer App, um eine bessere Leistung zu erzielen, nicht für Redux.

0
yairniz