2017-03-17 1 views
1

Sorry für die Art von vagen Titel. Der beste Weg, meine Frage zu erklären, könnte ein Beispiel sein.So verzögern Redux-Zustand Änderungen, um einen Nebeneffekt in einer Reaktionskomponente zu ermöglichen

Ich habe eine der Elemente in redux, und die Liste wird in einer reagierenden Komponente mit Standard-react-redux verbundenen Komponenten angezeigt. Jedes einzelne Element verfügt über eine Schaltfläche, die beim Klicken eine asynchrone Arbeit ausführt. Anschließend wird das Element aus der Liste entfernt und in eine andere Liste eingefügt, die an einer anderen Stelle angezeigt wird. Es ist wichtig, dass die Logik zum Starten der asynchronen Arbeit in redux behandelt wird, da dies für den Zustand meiner Anwendung wichtig ist.

Diese grundlegende Funktionalität funktioniert, aber jetzt möchte ich Feedback zu der Schaltfläche hinzufügen, so dass, wenn die Nebenwirkung erfolgreich ist, ändert sich die Bezeichnung zu einem Häkchen (der Einfachheit halber werde ich nichts tun und die Liste unverändert lassen, wenn die Anfrage schlägt in diesem Beispiel fehl). Der Gegenstand wird für eine weitere Sekunde mit dem Häkchen bleiben, bevor er von der Liste entfernt wird.

Das Problem ist, dass wenn ich das Element aus der Liste entfernen, sobald die asynchrone Arbeit erledigt ist, wird es sofort ausgehängt, also muss ich das verzögern. Ich habe versucht, eine Möglichkeit zu finden, diese Logik, die in meiner App wiederverwendbar ist, zu implementieren, da ich das Häkchen-Feedback in anderen Teilen der App verwenden möchte.

Die einfache Lösung besteht darin, eine Aktion mit Erfolg zu senden, die nur den Status ändert, um anzuzeigen, dass die Anforderung des Elements erfolgreich war, und dann eine setTimeout, um eine weitere Aktion eine Sekunde später auszuführen, um das Element tatsächlich aus der Liste zu entfernen.

Ich fühle mich wie diese Logik wird sehr repetitiv, wenn ich es an verschiedenen Orten in meiner App mache, wo ich einen Knopf habe. Ich möchte nicht in der Lage sein, die Zeitablauflogik für jede neue Schaltfläche zu wiederholen, die dies benötigt. Aber ich möchte, dass meine App den aktuellen Status meiner App anzeigt.

Hat sich jemand schon mal mit einem solchen Problem beschäftigt?

Dank

Edit: Ich glaube nicht, es ist wirklich die allgemeine Lösung ändern soll, aber ich bin mit redux-Loop-Nebenwirkungen zu behandeln. Ich fühle mich wie eine generische Lösung wird gut mit Thunk oder Saga oder was auch immer sonst funktionieren.

+0

Wenn Sie nicht bereits haben, finden Sie unter: http://stackoverflow.com/questions/35411423/how-to-dispatch-a-redux-action-with-a-timeout/35415559 – Derek

+0

Yep Ich habe gesehen, es. Meine Frage ist eher eine Frage der Architektur, wie man das wiederholt sauber macht, ohne die Logik überall zu wiederholen.Zum Beispiel habe ich in Item Reducer Logik, um zu speichern, welche Schaltflächen in welchen Zuständen sind. Aber ich möchte vermeiden, diese Art von Logik in einem separaten Reduzierer neu zu schreiben, der sich mit einem anderen Objekttyp beschäftigt. Eine Sache, an die ich gedacht habe, ist möglicherweise eine generische buttonState Reducer, die die Zustände für alle Tasten in der App behandelt. So ähnlich. Aber ich war interessiert zu sehen, ob die Leute Lösungen hatten, die zuerst funktionierten. – bdwain

Antwort

2

Sie erwähnten, dass Sie redux-loop verwenden, um Ihre asynchronen Daten zu verarbeiten. Ich bin vertrauter mit redux-thunk, also wenn es dir gut geht, gebe ich dir eine Antwort, die einen Thunk verwendet.

Sie können den Code DRY halten, wenn Sie den Timeout in Ihrer Aktion Schöpfer setzen und rufen Sie dann diese Aktion Schöpfer von mehreren Tasten:

// actionCreators.js 

const fetchTheThings = (url, successAction, failureAction, followUpAction) => (dispatch) => { 

    //if you put the app in an intermediate state 
    //while you wait for async, then do that here 
    dispatch({ type: 'GETTING_THINGS' }); 

    //go do the async thing 
    fetch(url) 
    .then(res => { 
     if (res.status === 200) return res.json(); 
     return Promise.reject(res); 
    }) 
    .then(data => { 
     //on success, dispatch an action, the type of which 
     //you passed in as an argument: 
     dispatch({ type: successAction, data }); 

     //then set your timeout and dispatch your follow-up action 1s later 
     setTimeout(() => { 
     dispatch({ type: followUpAction }); 
     }, 1000); 
    }) 
    .catch(err => { 
     //...and handle error cases 
     dispatch({ type: failureAction, data: err }); 
    }); 
}; 

//then you can have exported action creators that your various buttons call 
//which specify the action types that get passed into fetchTheThings() 

export const actionFiredWhenButtonOneIsPressed =() => { 
    return fetchTheThings('<some url>', '<success action>', '<failure action>', '<follow-up action>'); 
}; 

export const actionFiredWhenButtonTwoIsPressed =() => { 
    return fetchTheThings('<other url>', '<other success action>', '<other failure action>', '<other follow-up action>'); 
}; 

Hoffentlich, dass Sie einige Ideen zumindest gibt. Viel Glück!

+0

danke für Ihre Hilfe. Ich habe etwas implementiert, das dem ähnlich ist, was du beschrieben hast. Ich denke, idealerweise würde react einer Komponente erlauben, ihre eigene Unmountation zu verzögern, und das würde dies vereinfachen, weil es mir erlauben würde, die Statusaktualisierungen in reudx zu behalten und sich nur die Schaltfläche um diese verzögerte Unmount-Logik sorgen zu lassen. Aber das ist nicht implementiert, also ist dies die beste Option für jetzt. – bdwain

0

Ians Lösung sollte ziemlich gut, aber vielleicht verallgemeinerbar sein, wenn Sie mit einer Erfolgsbestätigung leben können, die nicht DOM-Aktivität erfordern:

Ein einfaches Aushängen Stil, der das Element grün wird und blendet sich dann heraus, wäre ausreichend für ein befriedigendes Benutzer-Feedback, um zu sagen, dass das Zeug funktioniert hat.

Verwandte Themen