How to handle two consecutive and dependent Async calls in Redux?

前端 未结 1 445
借酒劲吻你
借酒劲吻你 2021-02-01 22:36

I am getting a list of posts asynchronously by calling an action fetchPosts from a Component on componentDidMount. I would like, once that request is r

相关标签:
1条回答
  • 2021-02-01 23:33

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

    This is a pretty standard use-case for redux-thunk. The above example is catered towards the way you're asking the question, but you could accomplish this in a single action creator that looks the the redux-thunk example provided here: http://redux.js.org/docs/advanced/AsyncActions.html

    Whats different is that in my example, I'm dispatching a thunk inside of a thunk, rather than doing the second task directly inside of the first thunk. So its equivalent to this:

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

    You won't run into any race conditions because when you dispatch an action like { type: RECEIVE_POSTS, payload: res }, it is synchronous and the reducer updates before you dispatch the following async action.

    0 讨论(0)
提交回复
热议问题