2017-10-24 5 views
1

Ich erstelle ein Dashboard, das Elemente aus mehreren separaten Teilen einer SQL-Datenbank abrufen muss, um einen verwendbaren Speicher für die Anwendung zu erstellen. Die Aufrufe müssen sequentiell ausgeführt werden, da sie auf Daten des vorherigen Aufrufs angewiesen sind, um als Argument in nachfolgenden Aufrufen zu fungieren (BEISPIEL: ein Benutzername und ein Kennwort werden anfangs eingefügt, dies ermöglicht es uns, eine Benutzer-ID in der Datenbank zu finden dann verwenden Sie, um die Ziele zu lokalisieren, die für sie sichtbar sind, die wir dann verwenden können, um die tatsächlichen Daten über jedes Ziel zu greifen)Callback-Funktionen, die in Action Creator nicht ordnungsgemäß ausgeführt werden

Ich bin neu in Redux (und Async-Versprechen wie folgt zusammen zu verketten). Ich habe gedacht, dass der beste Weg, dies zu erreichen, darin besteht, die verschiedenen Versprechen in einem Action-Creator zusammenzufassen. Ich bekomme jedoch ein Verhalten, das ich nicht vollständig erklären kann.

Die Aktion Schöpfer ist unter:

export function setReduxStore(username, password) { 
    return function (dispatch) { 
    return dispatch(
     loginUser(username, password) 
    ).then((customerId) => 
     setAvailableTargets(customerId) 
    ) 
    } 
} 

Wie Sie die Aktion Schöpfer erste Feuer ‚Loginuser()‘ sehen. Dieser Teil wird korrekt ausgelöst. Der Code für die Anmeldung Benutzer finden Sie nachstehend:

export function loginUser(username, password) { 
    return function (dispatch) { 
    return axios({ 
     method: 'POST', 
     url: 'http://localhost:3050/users/login', 
     data: { 
     username: username, 
     password: password 
     } 
    }).then((response) => { 
     dispatch({type: "LOGIN_USER", payload: response}) 
     return response.data.data[0].customer_id 
    }) 
    } 
} 

jedoch in der ‚setReduxStore()‘ Aktion Schöpfer Ich habe es Setup dann eine zweite Abfrage auszulösen die verfügbaren Ziele zu helfen, festgelegt. Dieser Aufruf akzeptiert eine ID, die von der Benutzeranmeldung als Argument zurückgegeben wird. Der Code für diese Aktion ist unten:

export function setAvailableTargets(customer_id) { 
    return function (dispatch) { 
    console.log("set targets fired with customer Id " + customer_id) 
    return axios({ 
    method: 'GET', 
    url: 'http://localhost:3050/users/targets/' + customer_id, 
    data: { 
     customer_id: customer_id 
    } 
    }).then((response) => { 
    dispatch({type: 'SET_AVAILABLE_TARGETS', payload: response}) 
    return response.data.data[0].id 
    }) 
    } 
} 

Sie werden bemerken, dass ich in dieser Funktion eine Konsole Log-Anweisung haben - wenn ich es oben

setzen
return function (dispatch) 

Es wird mit der entsprechenden ID Feuer versehen von loginUser. Nichts unter der 'Rückgabefunktion (Versand)' wird jedoch ausgelöst. Wenn ich die Methode außerhalb der Versprechungskette anrufe, funktioniert sie. Es gibt also etwas über die Art und Weise, wie sie innerhalb des Aktionserzeugers aufgerufen wird, die die Funktion auslöst, aber nicht wirklich erlaubt, einen ihrer bedeutungsvollen Codeabschnitte auszuführen.

Nicht sicher, ob es wichtig ist, aber sobald dies herausgefunden ist, muss ich die Versprechenskette mehr aufbauen - und die tatsächlichen Daten basierend auf den IDs abrufen, die von setAvailableTargets() zurückgegeben werden.

EDIT: Für alle mit einem ähnlichen Problem, half die Antwort unter mir zu einer funktionierenden Sequenz führen, die wie folgt aussieht:

export function setReduxStore(username, password) { 
    return function (dispatch, getState) { 
    return dispatch(
     loginUser(username, password) 
    ).then(() => { 
     return dispatch (
     setAvailableTargets(getState().currentUser.customerId) 
     ) 
     }) 
    } 
} 

ich eine Funktion Brennen hatte, aber es war Dispatching nicht, was verhindert wurde es aus dem Ausführen eines sinnvollen Codes. Ich musste dafür sorgen, dass in jeder konkreten Phase der gebündelten Funktion ein neuer Versand erfolgt.

+0

Es gibt keinen Grund für Sie die Versprechungen zurück, wenn alles, was Sie tun, wartet auf sie weitere Aktionen zu lösen und den Versand.Es ist auch ein Anti-Pattern, um Werte von einem Redux-Aktionsersteller zurückzugeben. Verbinden Sie stattdessen Ihre Komponente, um den neuen Status als Ihre Geschäftsupdates zu erhalten. Versuchen Sie, die Return-Anweisungen vor Ihren Axios-Aufrufen zu entfernen. – kngroo

+0

Wenn ich das tue, erhalte ich den folgenden Fehler: "Fehler: Aktionen müssen einfache Objekte sein. Verwenden Sie angepasste Middleware für asynchrone Aktionen." –

+0

verwenden Sie Thunk Middleware für Redux? – kngroo

Antwort

1

Ausgehend von den obigen Kommentaren müssen Sie einfache Objekte aus Aktionen zurückgeben. Da Sie Redux Thunk Middleware verwenden, können Sie Funktionen als Aktionen zurückgeben.

export function setReduxStore(username, password) { 
    return function (dispatch) { 
    loginUser(username, password) 
     .then((customerId) => 
     dispatch(setAvailableTargets(customerId)) 
    ) 
    } 
} 

export function loginUser(username, password) { 
    return function (dispatch) { 
    axios({ 
     method: 'POST', 
     url: 'http://localhost:3050/users/login', 
     data: { 
     username: username, 
     password: password 
     } 
    }).then((response) => { 
     dispatch({type: "LOGIN_USER", payload: response}) 
     //return response.data.data[0].customer_id 
     // Get data from store instead 
    }) 
    } 
} 

export function setAvailableTargets(customer_id) { 
    return function (dispatch) { 
    console.log("set targets fired with customer Id " + customer_id) 
    axios({ 
     method: 'GET', 
     url: 'http://localhost:3050/users/targets/' + customer_id, 
     data: { 
     customer_id: customer_id 
     } 
    }).then((response) => { 
     dispatch({type: 'SET_AVAILABLE_TARGETS', payload: response}) 
     //return response.data.data[0].id 
     // Get data from store instead 
    }) 
    } 
} 

Ein gemeinsames Muster mit Asynchron-Aktionen in redux ist ‚Antrag‘, ‚Erfolg‘, ‚Versagen‘ Aktionstypen zu definieren, so dass Ihr UI weiß, ob eine Ladeanimation, Fehlermeldung oder Antwortdaten zu machen.

sehen: http://redux.js.org/docs/advanced/AsyncActions.html

+0

Danke! Ich hatte meinen Kopf gegen diesen Code geschlagen, solange ich keine offensichtlichen Dinge in Erwägung zog. Als ich Ihr Beispiel sah, war es offensichtlich, dass ich einige Code-Teile hatte, die nichts unternahmen, und ich musste das neu strukturieren, was genau aufgerufen wurde. –

Verwandte Themen