2015-10-26 8 views
14

Ich erhalte eine Liste von Posts asynchron, indem ich eine Aktion fetchPosts von einer Komponente auf componentDidMount aufruft. Ich möchte, sobald diese Anfrage von dem entsprechenden Reduzierer (der den Status aktualisiert) empfangen und bearbeitet wird, eine weitere Aktion fetchPostsMetaData mit einem Array der gerade erhaltenen Posts-IDs aufrufen.Wie zwei aufeinanderfolgende und abhängige Async-Aufrufe in Redux behandeln?

I redux-thunk Middleware benutzt und meine AJAX-Anfragen machen jQuery.ajax

mit Was ist der beste Weg, um dies zu realisieren? Ich habe versucht zu googeln, konnte aber kein relevantes Beispiel/keine Antwort finden.

Antwort

10

Mit redux-thunk:

class PostIndex extends React.Component { 
    componentDidMount() { 
    const { dispatch } = this.props; 
    dispatch(getPosts()); 
    } 
    ... 
} 

function fetchPosts() { 
    return dispatch => { 
    fetchPostsAjax() 
     .then(res => { 
     dispatch({ type: 'RECEIVE_POSTS', payload: res }); 
     dispatch(fetchPostMeta(res)); 
     }) 
    } 
} 

function fetchPostMeta(posts) { 
    return dispatch => { 
    fetchPostMetaAjax(posts) 
     .then(res => dispatch({ type: 'RECEIVE_POST_META', payload: res })); 
    } 
    } 
} 

function fetchPostAjax() { 
    // return a promise, whether from jQuery.ajax or fetch 
} 

function fetchPostMetaAjax() { 
    // return a promise 
} 

Das ist eine ziemlich Standard-Use-Case für redux-thunk. Das obige Beispiel ist auf die Art und Weise versorgen Sie die Frage fragen, aber man konnte dies in einem einzigen Aktion Schöpfern erreicht, dass die das redux-thunk Beispiel hier zur Verfügung gestellt sieht: http://redux.js.org/docs/advanced/AsyncActions.html

Was anders ist, dass in meinem Beispiel, ich bin einen Thunk innerhalb eines Thunk entsenden, anstatt die zweite Aufgabe direkt innerhalb des ersten Thunks zu erledigen. So ist es entspricht dies:

function fetchPosts() { 
    return dispatch => { 
    fetchPostsAsync() 
     .then(res => { // res is posts 
     dispatch({ type: 'RECEIVE_POSTS', payload: res }); 
     return fetchPostMetaAsync(res); 
     }) 
     .then(res => { // res is metadata 
     dispatch({ type: 'RECEIVE_POST_META', payload: res }); 
     }) 
    } 
} 

Sie werden nicht in irgendwelche Rennbedingungen laufen, weil, wenn Sie eine Aktion wie { type: RECEIVE_POSTS, payload: res } versenden, es synchron ist und die Reduktions Updates, bevor Sie versenden die folgende async Aktion.

+0

Ja, das scheint perfekt zu funktionieren und macht Sinn. Vielen Dank! Am Ende habe ich es wie im zweiten Beispiel getan, das nur "then" durch "$ .ajax" ({... success: function (result) {...}}) ersetzt. Sie haben auch einen wiederholenden 'fetchPosts()' Aufruf in Ihrem ersten Beispiel, möchten vielleicht den ersten zu 'getPosts()' bearbeiten, damit er verständlicher ist. Danke nochmal! – liorbrauer

+1

Danke, dass du darauf hingewiesen hast! Ich habe es korrigiert. Ich denke, das zweite Beispiel ist idiomatischer und Versprechen sind lustig also: thumbsup: –

Verwandte Themen