Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mapStateToProps is not always called synchronously #1088

Closed
kambing86 opened this issue Nov 21, 2018 · 12 comments
Closed

mapStateToProps is not always called synchronously #1088

kambing86 opened this issue Nov 21, 2018 · 12 comments

Comments

@kambing86
Copy link

found a very hard to trace bug in my app and it seems like mapStateToProps is not being called the same. I'm able to replicate the behaviour in codesandbox

https://codesandbox.io/s/m075w1wq8

AppContainer is the parent
AppContainer2 is the child

before dispatch
parent mapStateToProps 1
after dispatch
child mapStateToProps 1

check the console.log and found that parent's mapStateToProps is being called synchronously, which is within the dispatch call, but the child's mapStateToProps is being called after dispatch call

I think this is because the subscription in the connect function is trying to defer it after componentDidUpdate in the parent

please close this if this is intended

@markerikson
Copy link
Contributor

@kambing86 : yes, that's expected behavior in 5.x . v5 implements nested subscription behavior, where child components are only notified after the parent has finished updating.

What actual bug is this causing in your application?

@timdorr timdorr closed this as completed Nov 21, 2018
@kambing86
Copy link
Author

well, when there is logic involving redux state and local state of Component.

depending on the placement of the Container, the redux state is not notified to the Component in time and local state will be updated to the Component before redux state, even the setState is after dispatch action

we always assume that the redux state should be always notified to Component in synchronous manner when dispatching action, but this is not the case for react-redux, which is not really being mentioned in any documentation

@markerikson
Copy link
Contributor

markerikson commented Nov 22, 2018

The exact timing of this has always been an implementation detail, and should not be relied on. (I'm writing a blog post right now that goes into the history of the implementation and how it's changed over time.)

I'd encourage you to try out our version 6 beta release, which switches to using createContext internally. It should be more consistent about how that's handled.

In fact, if I update the sandbox to use v6.0.0-beta.2, I see this output when I click a button:

before dispatch 
after dispatch 
parent mapStateToProps 
child mapStateToProps 

This makes sense, because the dispatch now only runs a single subscriber callback - in the <Provider>. The connected components are now running mapState as part of React re-rendering the tree.

@gaurav5430
Copy link

was there a blog post to describe this behaviour ?

@markerikson
Copy link
Contributor

@gaurav5430 sort of. Closest would be my post The History and Implementation of React-Redux , which describes how our implementation has evolved over time.

Out of curiosity, why the question on a 2.5-year-old issue?

@gaurav5430
Copy link

i am just trying to understand the react component re-rendering if multiple dispatch calls happen one after the other.
would every dispatch lead to a re-render assuming it changes the subscribed state
or would it somehow be batched, or it depends on something else as well?

This is one of the top searches for my query, so asked here

i was able to find your article through another thread, it is great, and gave me a lot of understanding, but I still did not get enough understanding about what is the expected behaviour here

@markerikson
Copy link
Contributor

See my other post A (Mostly) Complete Guide to React Rendering Behavior for details on how React batching works.

The other factor is that React-Redux v7 also uses batching internally.

@gaurav5430
Copy link

have gone through that article as well. it is great and has a lot of details, but still does not answer my question certainly I guess. will try to re-read both of those

Any way to see the internal batching of react redux v7 ?

i think that is what I may be experiencing

@gaurav5430
Copy link

i got this from the article that v7 uses batchedUpdates internally, but does that mean that all dispatches which happen in one tick and impact React tree, can always be expected to be batched, and never execute synchronously ?

@markerikson
Copy link
Contributor

The dispatches themselves are synchronous. The re-rendering of the UI is batched.

This issue really isn't a good place to provide support. If you're having problems, the best option is to ask in either Stack Overflow or Reactiflux, and provide a CodeSandbox or repo that demonstrates whatever problem you're seeing, rather than sort of poking around at implementation details.

@gaurav5430
Copy link

yeah ok, makes sense.

More than facing a problem i am just trying to understand the potential behaviour of how multiple disptatches within a single tick would impact the component re-rendering.

Will ask on SO

@gaurav5430
Copy link

Actually, will just mention here for completion:
looking at this issue: #1437
I just tested my multiple dispatch implementation, and it gave me an understanding that multiple dispatches in a single tick are synchronous, but the UI updates are batched, and it is a dependable behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants