Was ist die beste Vorgehensweise, um Daten in componentDidUpdate abzuleiten, diese in den Redux-Speicher zu verschieben, aber dann auch diese Daten zu verwenden, um weitere Daten abzuleiten und diese erneut in den Redux-Speicher zu verschieben?

Da Redux synchron ist, hatte ich gehofft, direkt nach dem Versand auf den aktualisierten Store zugreifen zu können, aber ich gehe davon aus, dass Requisiten nicht mit den neuen Store-Daten über {{aktualisiert wurden, da sie sich noch im componentDidUpdate befinden X0}}. d.h. ich habe versucht -

componentDidUpdate(){
    this.determineAndStoreA()
    this.doSomethingElse(this.props.A) // hoping this would be the updated A
}

this.props.A ist immer noch der alte Wert

Sollte ich so etwas wie sein -

componentDidUpdate(){
    const a = this.determineA()
    this.storeA(a);
    this.doSomethingElse(a) // using a local copy of A
}

Bei einigen weiteren Untersuchungen fand ich eine ähnliche Frage in https://github.com/reduxjs / React-Redux / Issues / 291. Dan empfiehlt, auf die Aktion im Reduzierer zu reagieren, aber das scheint, als müsste ich jetzt die Logik kombinieren, A zu bestimmen, B aus A zu bestimmen, A und B gleichzeitig zu speichern?

4
andy mccullough 18 Jän. 2019 im 17:25

3 Antworten

Beste Antwort

Ich glaube, ich sehe, womit Sie zu kämpfen haben. Lassen Sie mich zunächst versuchen, das Szenario, mit dem Sie sich meiner Meinung nach befassen, genauer zu beschreiben.

Sie haben A und B in Ihrem Geschäft. C wird von A und B abgeleitet. Wenn sich also A ändert, möchten Sie C erneut ableiten und in Ihrem Geschäft ablegen. Sie könnten dann eine Komponentenstütze E haben, die von C und D abgeleitet ist. Aktion x ändert A und jetzt benötigen Sie den neuen Wert für C oder E. Es ist schwierig, dies in einem Schritt zu tun, ohne die Reduzierungen zu kompliziert zu machen.

Es gibt drei Hauptansätze, die ich für solche Szenarien verwendet habe, und welcher ich empfehlen würde, hängt von den Besonderheiten des Szenarios ab. All dies sind nur unterschiedliche Ansätze, wie / wann / wo C zu bestimmen ist (und könnten auf weitere Ableitungen wie E erweitert werden).

Ansatz 1 Berechnen Sie C in Middleware, die für den Umgang mit Nebenwirkungen von Aktionen entwickelt wurde.

Dies ist der Ansatz, der dem am ähnlichsten ist, den Sie bereits haben. Es verschiebt es einfach aus einer Komponente heraus, damit Sie nicht gegen die Interaktion zwischen Ihrem Geschäft und dem Erhalt der neuen Informationen durch Lebenszyklusmethoden kämpfen. Für diesen Ansatz würde ich Redux Saga verwenden und es veranlassen, C als Antwort auf die Aktion x zu berechnen und die Aktion auszulösen, um den Speicher mit dem neuen Wert für C zu aktualisieren. Dies ist einfach (wenn Sie die anfängliche Lernkurve für Redux Saga überschritten haben), da Redux Saga die Aktion erhält, nachdem der Store bereits aktualisiert wurde. Der Hauptnachteil dieses Ansatzes besteht darin, dass sich Ihr Geschäft vorübergehend in einem inkonsistenten Zustand befindet, in dem C die Änderung zu A noch nicht widerspiegelt. Für einige Szenarien ist dies wichtig und für andere nicht. Der andere mögliche Nachteil ist, dass wenn Sie Redux Saga noch nicht verwenden, dies zunächst ein wenig einschüchternd sein kann, da sich die Verwendung von Generatorfunktionen und yield und die gesamte Denkweise bei der Verwendung von Redux Saga etwas fremd anfühlen können ( Aber ich liebe es wirklich, Redux Saga für komplexe asynchrone Szenarien zu verwenden.

Ansatz 2 Berechnen Sie C in einem Aktionsersteller.

Dies beinhaltet im Allgemeinen die Verwendung eines Thunks für die erste Antwort auf die Aktion x. Der Thunk kann dann B aus dem Geschäft holen, C berechnen und eine Aktion mit einer Nutzlast auslösen, die zwei Teile enthält. - eine, die vom Reduzierer für A und eine vom Reduzierer für C verwendet wird. Der Hauptnachteil dieses Ansatzes besteht darin, dass sich die Abhängigkeiten für C (dh A und B) ändern können. Dies kann jedoch zu einer komplizierten Methode zum Organisieren von Dingen werden In einigen Szenarien kann es gut funktionieren. Ich habe mich größtenteils von diesem Ansatz zugunsten der beiden anderen Ansätze entfernt.

Ansatz 3 Legen Sie C nicht in Ihr Geschäft.

Wenn C vollständig von anderen Dingen in Ihrem Geschäft abgeleitet ist, muss es nicht wirklich im Geschäft sein. C ist nur eine Ansicht anderer Informationen in Ihrem Geschäft. Sie können stattdessen einen Selektor für diesen Zweck verwenden. Wenn es teuer ist, C abzuleiten, verwenden Sie einen gespeicherten Selektor. In dem komplizierteren Fall, dass auch E von C und D abgeleitet ist, kann ein Selektor für E den Selektor für C nutzen, während { {X8}} aus dem Laden. Dies ist der Ansatz, den ich im Allgemeinen bevorzuge, es sei denn, es gibt einen zwingenden Grund dafür, dass C im Geschäft ist. Dieser Ansatz ermöglicht es Ihren Reduzierern, einfach und unabhängig zu bleiben und gleichzeitig Ihr Geschäft in einem konsistenten Zustand zu halten.

Andere Ansätze

Es gibt andere Möglichkeiten, dies zu tun, aber die drei oben genannten Ansätze habe ich tatsächlich selbst verwendet. Eine andere Möglichkeit besteht darin, ein Reduzierstück zu haben, das andere Reduzierstücke nutzt. Bei diesem Ansatz werden die Reduzierer für A und B von einem Reduzierer verwendet, der dann C berechnet und den Status mit allen drei Informationen zurückgibt. Es gibt Pakete, die es einfacher machen, Reduzierungen auf diese Weise zusammenzustellen, aber ich habe sie nicht verwendet, weil ich an diesem Ansatz nicht sehr interessiert bin. Für mich ist es einfach der falsche Ort, um diese Komplexität zu setzen.

1
Ryan Cogswell 18 Jän. 2019 im 16:54

Sie erhalten die aktualisierte Requisite nicht im selben Zyklus, in dem Redux den Wert in den Speicher schiebt und eine weitere Aktualisierung der Komponente auslöst.

Müssen Sie wirklich beide Aktionen von componentDidUpdate aus auslösen?

Sie können eine neue Aktion erstellen, die von der Aktion ausgelöst wird, in der Sie Ihren A-Wert gespeichert haben.

Etwas wie das

store.dispatch(saveValueA()).then(() =>
  doSomeAction()
);
0
Ales Maticic 18 Jän. 2019 im 14:50

Ihre Komponente wird jedes Mal neu gerendert, wenn sich A ändert, und componentDidUpdate wird aufgerufen.

Sie können dann so etwas tun wie:

componentDidUpdate(prevProps){

    const hasAChanged = this.props.A !=== prevprops.A;

    if (hasAChanged) {
        this.determineAndStoreA()
    } else {
        this.doSomethingElse(this.props.A)
    }
}

Ich bin mir nicht sicher, was Sie versuchen, hoffe, es hilft.

0
Erwan Haquet 18 Jän. 2019 im 15:09