2015-10-26 12 views
14

Ricevo un elenco di post in modo asincrono chiamando un'azione fetchPosts da un componente su componentDidMount. Vorrei che, una volta ricevuta la richiesta e gestita dal relativo riduttore (che aggiorna lo stato), venga chiamata un'altra azione fetchPostsMetaData, con una matrice di ID dei messaggi appena ricevuti.Come gestire due chiamate asincrone consecutive e dipendenti in Redux?

Sto usando redux-thunk middleware, e fare le mie richieste Ajax utilizzando jQuery.ajax

Qual è il modo migliore per andare su questo? Ho provato googling ma non ho potuto trovare un esempio/risposta pertinente.

risposta

10

Utilizzando 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 
} 

Si tratta di un caso d'uso abbastanza standard per redux-thunk. L'esempio precedente è approvvigionato verso il modo in cui si sta ponendo la domanda, ma si potrebbe ottenere questo risultato in un unico creatore azione che guarda l'esempio redux-thunk fornito qui: http://redux.js.org/docs/advanced/AsyncActions.html

cosa è diverso è che nel mio esempio, io sono invio di un thunk all'interno di un thunk, piuttosto che eseguire il secondo task direttamente all'interno del primo thunk. Quindi, il suo equivalente a questo:

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 }); 
     }) 
    } 
} 

Non incorrere in eventuali condizioni di gara, perché quando si spedizione un'azione come { type: RECEIVE_POSTS, payload: res }, è sincrono e gli aggiornamenti riduttore prima di voi inviare i seguenti azione asincrona.

+0

Sì, sembra funzionare perfettamente e ha senso. Grazie! Ho finito per farlo come il secondo esempio che hai fornito solo sostituendo 'then' con' $ .ajax di jQuery ({... success: function (result) {...}}) '. Inoltre, hai una chiamata 'fetchPosts()' nel tuo primo esempio, potresti voler modificare la prima in 'getPosts()' per renderla più comprensibile. Grazie ancora! – liorbrauer

+1

Grazie per avermelo fatto notare! L'ho corretto. Penso che il secondo esempio sia più idiomatico e le promesse sono divertenti: thumbsup: –

Problemi correlati