Reputation: 1334
I am new to Redux. I have to dispatch an action to update the state of my application and then use the updated state to call my back-end. I use the thunkMiddleware
.
const mapDispatchToProps = dispatch => bindActionCreators({
login: (user) => dispatch => {
dispatch(loginAction())
console.log('user.loggedIn after loginAction dispatching is', user.loggedIn)
}
}, dispatch)
I expect that immediately after the call to dispatch
my state (and all props mapped to it) will receive the updated value. However, it does not happen: the code after the dispatch
call still observes the state before update (i.e., in my example, false
gets printed to the console).
Is it by design that even though I dispatch an action to update the state, I do not observe the updated state in the same function? Or I am doing something wrong? Thank you in advance!
The reproduction project is available here.
Upvotes: 2
Views: 4472
Reputation: 67439
The other two comments are at least partly incorrect.
Dispatching an action is 100% synchronous by default, assuming no middleware intercepts the action and delays it. As soon as dispatch()
returns, the store state has been updated. @ageoff 's example is correct in that you could call getState()
in a thunk again after dispatching and see the updated state.
There are two problems in your code sample.
First, after dispatching, React has not had a chance to re-render, so the component's props will not have changed.
Second, your reducer should be returning a new object in response to the action, so the existing user
object will not be the updated reference. In fact, if you're properly doing immutable updates, that old user
object will never change. When the component re-renders, it should get a new value for props.user
, with the changes.
Upvotes: 4
Reputation: 2828
As mentioned the dispatch is not immediate. The component will have to wait for the props to be sent to it in the next render. I would suggest moving any logic the needs the immediate values into the reducer itself:
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
}
}
Upvotes: 2
Reputation: 972
dispatch
is async, if the login code is promise returning you could call .then
on the action, but it would be better to think about how else you can achieve the same thing.
The docs linked mention
It was fully synchronous. Every time an action was dispatched, the state was updated immediately.
which may be the source of confusion? The instant update refers to the next state, which you should be able to observe in the component or mapStateToProps
Upvotes: 0