最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ReactJS + Redux: How to wait until dispatch has been completed before moving onto next step? - Stack Overflow

programmeradmin4浏览0评论

In ReactJS + Redux project, I have a method where it makes an API request. If successful, I would like to dispatch another action creator and wait until it finishes. Then when it pletes, move onto the next step.

Currently, the following code does the dispatch where it makes another API call but even before the state gets updated via dispatch, it immediately executes window.location.href ='http://localhost:3005/#/Home' and then the dispatch gets pleted afterwards.

So how can I wait until the dispatch(actions.updateUserInfo(userInfo.username)) gets pleted before executing the next line of code, window.location.href ='http://localhost:3005/#/Home'?

Here is the action creator:

  loggingIn(userInfo) {

    var userInfoBody = {
        'username': `${userInfo.username}`,
        'password': `${userInfo.password}`
    }

    var configuration = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userInfoBody)
    }

    return function(dispatch) {
      fetch(':8080/creds', configuration)
      .then(response => response.json())
      .then(response => {
        //Would like to finish this dispatch pletely before start executing window.location.href ='http://localhost:3005/#/Home'
        dispatch(actions.updateUserInfo(userInfo.username))
        window.location.href ='http://localhost:3005/#/Home'
      })
      .catch((error) => {
        console.log("Error: ", error)
      })
    }

Thank you in advance

In ReactJS + Redux project, I have a method where it makes an API request. If successful, I would like to dispatch another action creator and wait until it finishes. Then when it pletes, move onto the next step.

Currently, the following code does the dispatch where it makes another API call but even before the state gets updated via dispatch, it immediately executes window.location.href ='http://localhost:3005/#/Home' and then the dispatch gets pleted afterwards.

So how can I wait until the dispatch(actions.updateUserInfo(userInfo.username)) gets pleted before executing the next line of code, window.location.href ='http://localhost:3005/#/Home'?

Here is the action creator:

  loggingIn(userInfo) {

    var userInfoBody = {
        'username': `${userInfo.username}`,
        'password': `${userInfo.password}`
    }

    var configuration = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userInfoBody)
    }

    return function(dispatch) {
      fetch('https://backendserver.:8080/creds', configuration)
      .then(response => response.json())
      .then(response => {
        //Would like to finish this dispatch pletely before start executing window.location.href ='http://localhost:3005/#/Home'
        dispatch(actions.updateUserInfo(userInfo.username))
        window.location.href ='http://localhost:3005/#/Home'
      })
      .catch((error) => {
        console.log("Error: ", error)
      })
    }

Thank you in advance

Share Improve this question asked Oct 12, 2016 at 20:11 user3259472user3259472 1
  • stackoverflow./a/66616697/6117565 – bikram Commented Mar 14, 2021 at 5:39
Add a ment  | 

5 Answers 5

Reset to default 1

Probably the most redux-way to do this would be by introducing yet another action to which you'll react by doing your window.location.href = '...' stuff.

Since redux can be considered "single threaded" you can be sure that between each call to dispatch your state tree is fully updated.

dispatch(actions.updateUserInfo(userInfo.username))
// It's guaranteed that at this point your updateUserInfo action is handled and state tree is updated
dispatch(actions.userInfoUpdated(userInfo.username))

New action "userInfoUpdated" you would then handle in a redux middleware by doing the window.location.href = '...' thing.

If you return the fetch promise from your thunks, then you can continue the promise chain from the caller. Modified your code assuming updateUserInfo returns the fetch promise:

return function(dispatch) {
  return fetch('https://backendserver.:8080/creds', configuration)
  .then(response => response.json())
  .then(response => {
    //Would like to finish this dispatch pletely before start executing window.location.href ='http://localhost:3005/#/Home'
    dispatch(actions.updateUserInfo(userInfo.username))
     .then(() => {
       window.location.href ='http://localhost:3005/#/Home'
     })
  })
  .catch((error) => {
    console.log("Error: ", error)
  })
}

But I'd move the call to the second thunk (updateUserInfo) into the React ponent since the first thunk (loggingIn) is doing too much imo. Single Responsibility Principle and all that.

A way to do this that doesn't require to manually subscribe to the store and doesn't require any middleware (as suggested by the other answers) can be the following:

Reducer:

function userReducer (state={ doneUpdating: false, userData: null }, action) {
  if (action.type === 'UPDATE_USER_INFO') { // this is the action dispatched by updateUserInfo
    return {  ...state, userData: action.payload, doneUpdating: true }
  }
}

Component:

class YourComponent {
  ponentWillReceiveProps (nextProps) {
    if (!this.props.doneUpdating && nextProps.doneUpdating) {
      window.location.href ='http://localhost:3005/#/Home'
    }
  }

  // Rest of your ponent methods here...
}

function mapStateToProps (state) {
  return { doneUpdating: state.userReducer.doneUpdating }
}

connect(mapStateToProps)(YourComponent)

Basically, after you're done updating the state, you set a flag. You ponent (connected with Redux) reads that flag from the state and in ponentWillReceiveProps you detect the change and react (pun intended :)) accordingly. Depending on your case, you may need to perform the same check/redirect logic in ponentWillMount. This is needed if you need to dispatch you user update action when your ponent is not mounted already. In that case, the doneUpdating flag can bee true before the ponent gets mounted, and ponentWillReceiveProps won't be called.

Put your window.location.href ='http://localhost:3005/#/Home' in your subscribe handler. And make sure you subscribe for the event:

constructor(props, children)
{
    TheStore.subscribe( this.listenForDispatch.bind( this ) );
}

listenForDispatch()
{
    //Check the state is what you want
    if ( TheStore.getState().someProp == "somevalue" )
    {
        //Call it here!
        window.location.href ='http://localhost:3005/#/Home'
    }
}

EDIT: Before you start using Redux in your code, you need to read their documentation and tutorial. subscribe is one of the basic pieces of how Redux is used.

Use react-query, it has more features for fetching data and supporting your need

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论