2

我是 Redux 的新手。我必须调度一个动作来更新我的应用程序的状态,然后使用更新后的状态来调用我的后端。我使用thunkMiddleware.

const mapDispatchToProps = dispatch => bindActionCreators({
    login: (user) => dispatch => {
        dispatch(loginAction())
        console.log('user.loggedIn after loginAction dispatching is', user.loggedIn)
    }
}, dispatch)

我希望在调用我的状态(以及映射到它的所有道具)之后立即收到更新的值。dispatch但是,它不会发生:dispatch调用之后的代码仍然观察更新之前的状态(即,在我的示例中,false打印到控制台)。

即使我调度了一个动作来更新状态,我是不是有意在同一个函数中观察到更新的状态?或者我做错了什么?先感谢您!

复制项目可在此处获得。

4

3 回答 3

3

其他两条评论至少部分不正确。

默认情况下,调度动作100% 同步的,假设没有中间件拦截动作并延迟它。返回后dispatch(),商店状态已更新。@ageoff 的示例是正确的,因为您可以getState()在调度后再次调用 thunk 并查看更新的状态。

您的代码示例中有两个问题。

首先,在 dispatch 之后,React 还没有机会重新渲染,所以组件的 props 不会发生变化。

其次,您的 reducer 应该返回一个新对象以响应该操作,因此现有user对象不会是更新后的引用。事实上,如果您正确地进行不可变更新,那么旧user对象将永远不会改变。当组件重新渲染时,它应该获得一个新的值props.user,随着更改。

于 2018-08-29T19:03:52.923 回答
2

如前所述,调度不是立即的。该组件将不得不等待在下一次渲染中将道具发送给它。我建议将需要立即值的任何逻辑移动到减速器本身:

export const loginAction = () => {
  return (dispatch, getState) => {
    //Do your login stuff
    getState().user.loggedIn // = false
    dispatch(setUserLoggedIn(true))
    getState().user.loggedIn // = true
    //Make my back end calls
  }
}

于 2018-08-29T18:47:38.710 回答
0

dispatch是异步的,如果登录代码承诺返回,您可以调用.then该操作,但最好考虑如何实现相同的目标。

文档链接提及

它是完全同步的。每次调度一个动作时,状态都会立即更新。

这可能是混乱的根源?即时更新是指下一个状态,您应该能够在组件中观察到或mapStateToProps

于 2018-08-29T18:42:36.663 回答