简体   繁体   中英

React/Redux chaining async thunk actions at component level

What is the recommended way to chain dependent asynchronous redux thunk actions at the component level?

My use case is a flow where I need to first make an api call to retrieve a user object, then grab all blog posts for that user. The catch is that the second call to grab all blog posts is dependent on the first calls return value (user id).

My component:

export default class UserDetail extends React.Component
{
  componentDidMount() {
    this.props.getUser()
  }
}

this.props.getUser() returns a user object which I map to props:

const mapStateToProps = (state) => {
  return {
    user: state.user
  }
}

I need to call this.props.getBlogPostsForUser(USER_ID) after this.props.getUser() has completed. What is the recommended best practice to chain actions in this way?

You can chain thunks

const getUser = username => dispatch => request(username)
  .then(res => dispatch({ type: GET_USER })
  .catch(err => dispatch({ type: GET_USER_ERR }));

const getBlogPostsForUser = userId => dispatch => request(userId)
  .then(res => dispatch({ type: GET_BLOGS }))
  .catch(err => dispatch({ type: GET_BLOGS_ERR }));


const getUserAndPosts = username => (dispatch, getState) => dispatch(getUser(username))
  .then(() => {
    const user = getState().user;
    return dispatch(getBlogPostsForUser(user.id));
  });

Or you can combine them to one dispatch but then they are tied together

const getUserAndPosts = (username) => dispatch => request(username)
  .then((userData) => {
    dispatch(setUser(userData));
    return request(user.id)
      .then(blogs => dispatch(setBlog(blogs)));
  });

You have to identify the new user response coming in componentDidUpdate lifecycle method to call another dependent call. Like this

export default class UserDetail extends React.Component {
  componentDidMount() {
    this.props.getUser();
  }
  componentDidUpdate(prevProps) {
    const { user, getBlogPostsForUser } = this.props;
    const { user: prevUser } = prevProps;
    if (prevUser !== user) {
      const { USER_ID } = user; // derive USER_ID from user object. I dont know path. you can accordingly change
      getBlogPostsForUser(USER_ID);
    }
  }
}

This should work. Feedbacks are welcome

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM