React-Redux: Sollten alle Komponentenzustände im Redux Store aufbewahrt werden


88

Angenommen, ich habe einen einfachen Schalter:

Wenn ich auf die Schaltfläche klicke, wechselt die Farbkomponente zwischen Rot und Blau

Ich könnte dieses Ergebnis erzielen, indem ich so etwas mache.

index.js

Button: onClick={()=>{dispatch(changeColor())}}
Color: this.props.color ? blue : red

container.js

connect(mapStateToProps)(indexPage)

action_creator.js

function changeColor(){
 return {type: 'CHANGE_COLOR'}
}

reducer.js

switch(){
case 'CHANGE_COLOR':
return {color: true}

Aber das ist verdammt viel Code, um etwas zu schreiben, das ich mit jQuery, einigen Klassen und einigen CSS in 5 Sekunden hätte erreichen können ...

Ich denke also, was ich wirklich frage, ist, was mache ich hier falsch?


6
React-Redux wird nicht als etwas verkauft, das kürzer als jquery ist. Es braucht definitiv Code, um es zum Laufen zu bringen.
Zerkms

1
Schauen Sie hier: github.com/rackt/redux/issues/1287 Es gibt viele gute Diskussionen zu diesem Thema.
m0meni

1
danke @ AR7 das ist perfekt
l2silver

1
@ l2silver kein Problem. Grundsätzlich besteht die Idee darin, dass, wenn die Farbe dieser Komponente für niemanden von Bedeutung ist, dieser Status nur innerhalb der Komponente selbst beibehalten wird.
m0meni

2
Das erwähnte Problem AR7 wurde verschoben: github.com/reactjs/redux/issues/1287
ptim

Antworten:


152

Redux ist hauptsächlich für den "Anwendungsstatus" vorgesehen. Das heißt, alles, was mit Ihrer Anwendungslogik zu tun hat. Die darauf erstellte Ansicht spiegelt diesen Zustand wider, muss diesen Zustandscontainer jedoch nicht ausschließlich für alles verwenden, was er tut.

Stellen Sie einfach folgende Fragen: Ist dieser Status für den Rest der Anwendung wichtig? Werden sich andere Teile der Anwendung basierend auf diesem Status anders verhalten? In vielen kleineren Fällen wird dies nicht der Fall sein. Nehmen Sie ein Dropdown-Menü: Die Tatsache, dass es geöffnet oder geschlossen ist, hat wahrscheinlich keine Auswirkungen auf andere Teile der App. Die Verkabelung mit Ihrem Geschäft ist wahrscheinlich übertrieben. Es ist sicherlich eine gültige Option, bringt Ihnen aber keine wirklichen Vorteile. Du bist besser dran this.state, es einen Tag zu benutzen und zu nennen.

Wird in Ihrem Beispiel die Farbe dieser Schaltfläche umgeschaltet, um einen Unterschied in anderen Teilen der Anwendung zu bewirken? Wenn es sich bei einem Großteil Ihrer Anwendung um eine Art globales Ein- / Ausschalten handelt, gehört es definitiv in den Store. Wenn Sie jedoch nur auf eine Schaltflächenfarbe umschalten, wenn Sie auf die Schaltfläche klicken, können Sie den Farbstatus lokal definiert lassen. Das Klicken auf die Schaltfläche kann andere Auswirkungen haben, die einen Aktionsversand erfordern. Dies unterscheidet sich jedoch von der einfachen Frage, welche Farbe sie haben soll.

Versuchen Sie im Allgemeinen, Ihren Anwendungsstatus so klein wie möglich zu halten. Sie müssen nicht alles hineinschieben . Tun Sie es, wenn Sie müssen, oder es macht sehr viel Sinn, etwas dort zu behalten. Oder wenn es Ihnen das Leben mit Dev Tools erleichtert. Aber überladen Sie seine Bedeutung nicht zu sehr.


Hey, ich weiß, es wird nie eine endgültige Antwort auf diese Frage geben, aber ich denke, Ihre Logik ist hier sehr solide
l2silver

3
Um ehrlich zu sein, verstehe ich nicht wirklich, wozu das Flux / Redux-Ding überhaupt gut ist. Was war das Problem mit dem ereignisgesteuerten Modell?
Jayarjo

IMO, es ist nicht die perfekte Antwort. Es hängt davon ab, ob. Das Speichern des UI-Zustands in den Reaktionszustand macht den Redux-Speicher sauber, führt jedoch zu einer nicht funktionierenden Komponente, die schwer zu testen ist. Während das Speichern des UI-Zustands in den Reaktionszustand viele Anstrengungen für den Entwickler mit sich bringt, müssen wir zusätzliche Reduzierungen schreiben. Es gibt jedoch viele Pakete, die Ihnen dabei helfen können, Ihren UI-Status viel einfacher zu reduzieren. Weitere Informationen finden Sie unter redux.js.org/docs/faq/OrganizingState.html .
Ron

19

Redux FAQ: Organisationsstatus
Dieser Teil des offiziellen Redux-Dokuments hat Ihre Frage gut beantwortet.

Die Verwendung des lokalen Komponentenstatus ist in Ordnung . Als Entwickler ist es Ihre Aufgabe, zu bestimmen, welche Arten von Status Ihre Anwendung ausmachen und wo jeder Status leben soll. Finden Sie eine Balance, die für Sie funktioniert, und machen Sie mit.

Einige allgemeine Faustregeln für die Festlegung, welche Art von Daten in Redux eingefügt werden sollen:

  • Interessieren sich andere Teile der Anwendung für diese Daten?
  • Müssen Sie in der Lage sein, weitere abgeleitete Daten basierend auf diesen Originaldaten zu erstellen?
  • Werden dieselben Daten verwendet, um mehrere Komponenten anzutreiben?
  • Ist es für Sie von Wert, diesen Status zu einem bestimmten Zeitpunkt wiederherstellen zu können (dh Zeitreise-Debugging)?
  • Möchten Sie die Daten zwischenspeichern (dh den aktuellen Status verwenden, wenn er bereits vorhanden ist, anstatt ihn erneut anzufordern)?

6

Zum Hervorheben des großartigen Links von @ AR7 und weil sich dieser Link vor einiger Zeit verschoben hat:

Verwenden Sie Reagieren für einen kurzlebigen Status, der für die App global nicht wichtig ist und nicht auf komplexe Weise mutiert. Zum Beispiel ein Umschalten in einem UI-Element, ein Formulareingabestatus. Verwenden Sie Redux für Zustände, die global wichtig sind oder auf komplexe Weise mutiert sind. Zum Beispiel zwischengespeicherte Benutzer oder ein Post-Entwurf.

Manchmal möchten Sie vom Redux-Status in den React-Status wechseln (wenn das Speichern in Redux umständlich wird) oder umgekehrt (wenn mehr Komponenten Zugriff auf einen Status haben müssen, der früher lokal war).

Als Faustregel gilt: Tun Sie, was weniger umständlich ist.

Dan Abramov: https://github.com/reactjs/redux/issues/1287#issuecomment-175351978


-7

Ja, es lohnt sich , den gesamten Komponentenstatus in Redux zu speichern . Wenn Sie dies tun, profitieren Sie von vielen Funktionen von Redux wie dem Debuggen von Zeitreisen und wiederholbaren Fehlerberichten. Wenn Sie dies nicht tun, können diese Funktionen völlig unbrauchbar werden .

Jedes Mal, wenn Sie keine Änderung des Komponentenzustands in Redux speichern, geht diese Änderung vollständig aus dem Stapel der Redux-Änderungen verloren und die Benutzeroberfläche Ihrer Anwendung ist nicht mehr mit dem Speicher synchron. Wenn dies für Sie nicht wichtig ist, fragen Sie sich, warum Sie Redux überhaupt verwenden. Ihre Anwendung wird ohne sie weniger komplex sein!

Aus Leistungsgründen möchten Sie möglicherweise auf this.setState()alles zurückgreifen, was viele Aktionen wiederholt auslösen würde. Beispiel: Das Speichern des Status eines Eingabefelds in Redux jedes Mal, wenn der Benutzer einen Schlüssel eingibt, kann zu einer schlechten Leistung führen. Sie können dies lösen, indem Sie es wie eine Transaktion behandeln: Sobald die Benutzeraktion "festgeschrieben" ist, speichern Sie den endgültigen Status in Redux.

In Ihrem ursprünglichen Beitrag wird erwähnt, dass der Redux-Weg "verdammt viel Code zum Schreiben" ist. Ja, aber Sie können Abstraktionen für allgemeine Muster wie den lokalen Komponentenstatus verwenden.


Verbessertes Debuggen ist ein nützliches Ziel und eine nette Funktion von Redux, aber ich denke, das Signal-Rausch-Verhältnis ist auch wichtig. Man könnte jede Variable in einer Codebasis protokollieren, aber das würde viel zusätzlichen Code hinzufügen, was das Lesen des tatsächlichen Codes erschwert und das Protokollieren schwierig macht. Ich denke, dasselbe gilt für die Verwendung von Redux. Wenn alle Status in Redux enthalten sind, kann das Debuggen verbessert werden, aber es entstehen Kosten für zusätzlichen Code und Abstraktionen, die das Lesen von Code erschweren und sogar einige Debugging-Aufgaben erschweren können. (Und wenn die Redux Dev Tools abstürzen, gehen viele der Debugging-Gewinne verloren.)
JD Sandifer

1
Warum dann überhaupt Redux verwenden? Wenn Sie nicht alles in Redux einfügen, verlieren Sie alle Funktionen, z. B. devtools. Es ist wirklich alles oder nichts. Wenn Sie setState () für ein Dropdown-Menü wie in der oberen Antwort auf diesen Beitrag verwenden, können Sie devtools nicht zum Debuggen von Problemen verwenden, auf die Ihre Benutzer möglicherweise im Dropdown-Menü stoßen. Es ist schlimmer, wenn Sie setState () für ein Overlay verwenden, da es keine Möglichkeit gibt, vor und nach dem Anzeigen des Overlays Zeitreisen zu unternehmen. Das Besprühen von setState () hier und da ist sehr fehleranfällig, da der Entwickler ständig darüber nachdenken muss, was kaputt gehen könnte.
Kumar303

Als spezifischere Antwort ist das Protokollieren jeder Variablen in einer Codebasis keine hilfreiche Metapher, da die Frage lautet, ob this.setState()oder verwendet werden soll dispatch(action...). Man muss nicht this.setState()überall verwenden, aber wenn Sie müssen, ist mein Vorschlag, stattdessen Redux für 99% der Fälle zu verwenden, wobei this.setState()aufgrund von Leistungsproblemen auf 1% zurückgegriffen wird.
Kumar303

Das Protokollieren jeder Variablen scheint mir analog zu Redux zu sein und ist in der Regel gleichermaßen nicht ratsam. Wenn Sie einige Dinge aus Redux herauslassen, werden die Funktionen für alles, was sich in Redux befindet, nicht negiert, solange der Status getrennt ist. Das heißt, ich kann meine API-Aufruflogik, die über Redux geleitet wird, auch dann debuggen, wenn der Status eines Auswahlfelds nicht lautet. Das OP hat einen Punkt: Es erfordert mehr Code an mehreren Stellen, um Redux zu verwenden, und möglicherweise ist dies in dem aufgeführten Beispiel nicht gerechtfertigt.
JD Sandifer

Möglicherweise können Sie Ihre API-Logik tatsächlich nicht debuggen. Das ist mein Punkt. Es ist wirklich schwer vorauszusehen, in welchen Szenarien Sie die Zeitreise unterbrechen werden. Es ist daher besser, den gesamten Status (einschließlich des Auswahlfeldstatus) in Redux zu setzen, bis ein Leistungsproblem auftritt.
Kumar303
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.