redux ReactJS +还原型:如何等到派单完成后再进入下一步?

k10s72fa  于 2022-11-12  发布在  React
关注(0)|答案(5)|浏览(134)

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

先谢谢你了

9rbhqvlz

9rbhqvlz1#

也许最简化的方法是引入另一个操作,你可以通过执行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))

新的操作“userInfoUpdated”,您可以在redux中间件中通过执行window.location.href = '...'来处理。

wpcxdonn

wpcxdonn2#

如果从thunk返回fetch承诺,则可以从调用方继续该承诺链。修改代码时假定updateUserInfo返回获取承诺:

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)做了太多的imo、单一责任原则等等。

fzwojiic

fzwojiic3#

一种不需要手动订阅商店并且不需要任何中间件(如其他答案所建议的)的方法可以是:
异径管:

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中你检测到变化并做出相应的React(双关语:)。根据你的情况,你可能需要在componentWillMount中执行相同的检查/重定向逻辑。如果你需要在你的组件还没有挂载时分派你的用户更新操作,这是需要的。在这种情况下,doneUpdating标志可以在组件挂载之前变为true,并且componentWillReceiveProps不会被调用。

dw1jzc5e

dw1jzc5e4#

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

j2datikz

j2datikz5#

把你的window.location.href ='http://localhost:3005/#/Home'放到你的subscribe处理程序中,并确保你订阅了这个事件:

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的基本部分之一。

相关问题