Queuing Aktionen in Redux

Habe ich momentan noch eine situation, ich brauche wiedermal Aktionen, die ausgeführt werden, nacheinander. Ich habe schon einen Blick auf die verschiedenen middlewares, wie eine redux-Versprechen, die scheinen in Ordnung zu sein wenn Sie wissen, was das aufeinander folgende Aktionen sind an der Stelle der Wurzel (aus Mangel an eines besseren Begriffs) Aktion ausgelöst wird.

Im wesentlichen möchte ich pflegen eine queue von Aktionen, die Hinzugefügt werden können, um an jedem beliebigen Punkt. Jedes Objekt hat eine Instanz dieser Warteschlange in seinem Zustand abhängig und können die Aktionen in die Warteschlange eingereiht, verarbeitet und aus der Warteschlange entfernt entsprechend. Ich habe eine Implementierung, aber damit ich Zugriff auf bin Stand in meinem handeln Machern, die sich anfühlt wie ein anti-pattern.

Werde ich versuchen, und geben Sie den Zusammenhang der auf-und Umsetzung.

Use-Case -

Angenommen, Sie erstellen möchten einige Listen und speichern Sie Sie auf einem server. Bei der Listenerstellung, der server antwortet mit einer id für die Liste, die in nachfolgenden API-Endpunkte in Bezug auf die Liste:

http://my.api.com/v1.0/lists/          //POST returns some id
http://my.api.com/v1.0/lists/<id>/items //API end points include id

Vorstellen, dass der client ausführen möchte, optimistisch-updates auf diese API-Punkte zu verbessern, UX - niemand wird gerne auf der Suche auf Spinner. Also, wenn Sie erstellen eine Liste, die neue Liste sofort angezeigt wird, mit einer option auf Elemente hinzufügen:

+-------------+----------+
|  List Name  | Actions  |
+-------------+----------+
| My New List | Add Item |
+-------------+----------+

Nehme an, dass jemand versucht, ein Element hinzuzufügen, bevor die Antwort von der ersten create-Aufruf gemacht hat, es zurück. Der Artikel API ist abhängig von der id, so dass wir wissen können wir es nicht nennen, bis wir haben, die Daten. Aber vielleicht möchten wir optimistisch zeigen die neue Position und enqueue-Aufruf der API-Elemente, so dass es ausgelöst wird, sobald der create-Aufruf erfolgt ist.

Eine Mögliche Lösung

Die Methode, die ich verwende, um diese aktuell ist, indem jeder Liste eine action-queue - das ist eine Liste von Redux Aktionen, die ausgelöst wird, in Folge.

Reducer-Funktionen für die Listen-Erstellung könnte wie folgt Aussehen:

case ADD_LIST:
  return {
    id: undefined, //To be filled on server response
    name: action.payload.name,
    actionQueue: []
  }

Dann, in einer Aktion Schöpfer, wir würden enqueue-eine Aktion statt, die direkt auslösende es:

export const createListItem = (name) => {
    return (dispatch) => {
        dispatch(addList(name));  //Optimistic action
        dispatch(enqueueListAction(name, backendCreateListAction(name));
    }
}

Kürze halber wird angenommen, dass die backendCreateListAction Funktion ruft eine fetch API, die Nachrichten verteilt, um dequeue aus der Liste auf Erfolg/Misserfolg.

Das Problem

Was mich beunruhigt, ist hier die Umsetzung der enqueueListAction Methode. Dies ist, wo ich bin Zugriff auf Staat zu regieren, die Weiterentwicklung der Warteschlange. Es sieht wie folgt aus (ignorieren Sie das passende auf name - dieser name tatsächlich verwendet ein clientId in der Realität, aber ich versuche, damit das Beispiel einfach):

const enqueueListAction = (name, asyncAction) => {
    return (dispatch, getState) => {
        const state = getState();

        dispatch(enqueue(name, asyncAction));{

        const thisList = state.lists.find((l) => {
            return l.name == name;
        });

        //If there's nothing in the queue then process immediately
        if (thisList.actionQueue.length === 0) {
            asyncAction(dispatch);
        } 
    }
}

Hier davon ausgehen, dass der enqueue-Methode gibt einen einfachen Aktion fügt eine asynchrone Aktion in die Listen actionQueue.

Die ganze Sache fühlt sich ein bisschen gegen den Strich, aber ich bin mir nicht sicher ob es einen anderen Weg mit ihm zu gehen. Zusätzlich, da ich zum Versand in meinen asyncActions, ich übergeben zu müssen, den Versandweg zu Ihnen hinunter.

Gibt es ähnlichen code in der Methode dequeue aus der Liste, die löst die nächste Aktion sollte ein vorhanden:

const dequeueListAction = (name) => {
    return (dispatch, getState) => {
        dispatch(dequeue(name));

        const state = getState();
        const thisList = state.lists.find((l) => {
            return l.name === name;
        });

        //Process next action if exists.
        if (thisList.actionQueue.length > 0) {
            thisList.actionQueue[0].asyncAction(dispatch);
    }
}

Generell kann ich mit Leben, aber ich bin besorgt, dass es ein anti-pattern sein, und es könnte sein, ein präziser, idiomatische Weise, dies zu tun, in Redux.

Jede Hilfe ist willkommen.

  • Nehmen Sie einen Blick an redux-saga.
  • Dies ist eine große Frage, werde ich daran interessiert zu sehen, ob jemand eine elegante Lösung dafür. Ich habe mit Versprechen Ketten + mapDispatchToProps zu erreichen etwas ähnliches.
  • Ich denke, dass wir alle das getan haben, tief Tauchen Sie ein in reagieren/redux gefunden haben, müssen queue/Aggregat Aktionen in einer Weise, die nicht unterstützt wird, die speziell in einem der middleware-Optionen. Ich persönlich denke, du bist besser dran, Umgang mit es auf der Komponenten-Ebene, und tracking/Vergleich-Stand es, statt in der middleware, wo Sie müsste queue/dequeue-IDs.
  • Korrigieren Sie mich, wenn ich falsch Liege, aber ich glaube nicht, dass redux-saga, löst dieses Problem. Von dem, was ich sammeln können, von der Dokumentation, non-concurrent requests für die gleiche Aktion, die abgeholt werden, die von der saga stornieren ausstehende Anforderungen. Zugegeben, ich habe noch nicht gegraben zu tief in das Zeug noch.
  • Ich hoffe auf eine elegantere Lösung zu. Ich fühle mich immer noch wie ich vielleicht etwas grundlegend falsch oder nicht-idiomatische hier. Ich wäre interessiert zu sehen, Ihre Versprechen Ketten-Ansatz - funktioniert das, wenn Sie nicht wissen, die volle Versprechen Kette, wenn die Auslösung der ersten Aktion? Das war die größte Hürde für mich - ich muss in der Lage sein, beliebig hinzufügen und entfernen, die von dieser Warteschlange, wo Handlungen nicht wissen, ob es aufeinander folgende Aktionen.
  • Das ist interessant. Ich habe zunächst versucht zu lösen, in den Komponenten, aber ich war die überprüfung Zustand und Trigger-Aktionen in Warteschlangen, wenn Sie es in der render-Methode (also, dass, Wann immer gab es ein update, das Warteschlange könnte geprüft werden, und tickte vorbei). Dies trifft nicht Fliegen - Redux produziert eine Fehlermeldung über die render-Methode restlichen rein.
  • Ich würde den "Prozess" lokale Warteschlange" der Logik in eines der lifecycle-Methoden wie willReceiveProps.
  • Der Zugriff auf state-innen Ihre Aktion Schöpfer ist nicht ein anti-pattern. Mutiert wäre. Sehen Sie diese Umsetzung. github.com/cerebral/redux-action-tree
  • Ein großes Problem würde ich vorsichtig sein, der versucht, auf Daten zuzugreifen, die noch nicht existiert, und ich würde auf jeden Fall nicht zulassen, dass Zugriff auf Zustand von asynchronen Aktionen.
  • Also lassen Sie mich sicherstellen, dass ich verstehe. Sie möchten eine Warteschlange erstellen, der alle Aktionen, die ein Benutzer macht, das passiert in der Folge, sobald die Daten von der service zeigt sich? Auch nach oben, dass off Sie wollen, dass es auch mit dem async-Aktionen?
  • Check-out redux-Logik codewinds.com/blog/2016-08-16-business-logic-redux.html

InformationsquelleAutor MrHutch | 2016-08-03
Schreibe einen Kommentar