ReactJS + Redux:如何等到调度完成后再进入下一步



在ReactJS + Redux项目中,我有一个方法,它使API请求。如果成功,我想派遣另一个动作创建器并等待它完成。当它完成后,进入下一步。

当前,下面的代码执行调度,它调用另一个API,但甚至在通过调度更新状态之前,它立即执行window.location.href ='http://localhost:3005/#/Home',然后调度完成。

那么我怎么能等到dispatch(actions.updateUserInfo(userInfo.username))完成后再执行下一行代码window.location.href ='http://localhost:3005/#/Home'呢?

下面是动作创建器:

  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.com:8080/creds', configuration)
      .then(response => response.json())
      .then(response => {
        //Would like to finish this dispatch completely 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)
      })
    }

提前感谢

要做到这一点,最简单的方法可能是引入另一个操作,您将通过执行window.location.href = '…的东西。

由于redux可以被认为是"单线程的",因此可以确保在每个调度调用之间完全更新状态树。

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

新的操作" userinfoupupdated ",你可以在redux中间件中通过执行window.location.href = '…的东西。

如果您从您的服务器返回fetch承诺,那么您可以继续从调用者返回承诺链。修改代码,假设updateUserInfo返回fetch承诺:

return function(dispatch) {
  return fetch('https://backendserver.com:8080/creds', configuration)
  .then(response => response.json())
  .then(response => {
    //Would like to finish this dispatch completely 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)
  })
}

但是我会将调用移动到第二个thunk (updateUserInfo)到React组件中,因为第一个thunk (loggingIn)做得太多了。单一责任原则等等

一种不需要手动订阅存储且不需要任何中间件(如其他答案所建议的)的方法如下:

减速器:

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

组件:

class YourComponent {
  componentWillReceiveProps (nextProps) {
    if (!this.props.doneUpdating && nextProps.doneUpdating) {
      window.location.href ='http://localhost:3005/#/Home'
    }
  }
  // Rest of your component methods here...
}
function mapStateToProps (state) {
  return { doneUpdating: state.userReducer.doneUpdating }
}
connect(mapStateToProps)(YourComponent)

基本上,在完成状态更新之后,设置一个标志。您的组件(与Redux连接)从状态读取该标志,并在componentWillReceiveProps中检测更改并相应地做出反应(双关语)。根据您的情况,您可能需要在componentWillMount中执行相同的检查/重定向逻辑。如果您需要在组件尚未挂载时调度用户更新操作,则需要这样做。在这种情况下,doneUpdating标志可以在组件被挂载之前变为true,并且componentWillReceiveProps不会被调用。

window.location.href ='http://localhost:3005/#/Home'放入订阅处理程序中。记得订阅我们的活动:

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

编辑:在您开始在代码中使用Redux之前,您需要阅读它们的文档和教程。subscribe是如何使用Redux的基本部分之一

使用react-query,它有更多的功能来获取数据和支持您的需求

相关内容

  • 没有找到相关文章

最新更新