-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
setState() mutations and redux mutations are not batched into a single re-render #1298
Comments
The Codesandbox link you provided doesn't appear to have any of the code you mentioned in it. Can you update the link? |
@timdorr: updated. didn't realize I needed to explicitly save. |
These updates aren't batched together by default. You'll need to do this via the |
I was talking with him about this one in Reactiflux last night. I'd like to leave it open for the moment so I can remember to glance at it in the next few days, just to make sure I know what's happening here. |
@markerikson Thanks! @timdorr Even if they aren't batched, it seems that the ordering of the two re-renders aren't respecting React's dataflow from higher level to lower level components. The changes to |
Sorry, I was totally wrong about the batching. This has something to do with |
Huh, so any connected component that uses internal state should set |
I guess I should have started with a more basic question. Is my expectation of my provided event handler's behavior correct? Or should I account for the possibility that the |
@mgummelt : per our chat discussion, I would have expected that the |
Very glad that I was not the only one experiencing this issue 😛I experienced this issue when I upgrade the react-redux from v5 to v7. I tried to debug see why the redux store update only get passed down to the component in the later render call, and from the call stack it seems like the connected component was notified of store update only in the |
@stkao05 : yeah, we cascade notifications down the tree to enforce top-down update behavior. I don't have time to dig into this one myself atm, but if someone else can do so and report their findings, I'd appreciate it. |
We are also experiencing the same issue where a set state call and redux dispatch are not batched into one re-render despite being called within an event handler |
I have spent some time digging into this issue and I will share my findings here: The root cause of the issue is making the ConnectFunction a PureComponent by wrapping in Based on what I have read in blog, this step of making it pure was taken as part of performance optimization. But this optimzation is too aggresive, rather improper because ConnectFunction consumes the state inside the store, which is 'external' to this component in the sense that it does not reflect in its props. A workaround of using Expectation when you are In But this workaround is over-agressive. In v5.0.7's class component, However, wrapping the The main motiviation behind move from v5 to v6 and onwards, I believe, was to move from Legacy Context API to New Context API. Usage of function component is strictly not necessary to achieve this. So we could go back to Class component for Of course this will bring back |
@ckedar : thanks for digging into this! I appreciate the writeup. FWIW, we're not going back to a class component at this point. Not only would it be yet another complete rewrite, the complexities with trying to use context values in a class make it infeasible. (I actually did try to put together a class-based approach while working on v7, and gave up on that.) Part of the issue here is the tiered Subscription handling. A nested connected component will end up getting rendered later with the right store state, but given the current implementation, the I'm not sure if there's a good solution for this issue. Overall, this is somewhat of an edge case. Worst comes to worst, we document as a known issue as we did with "zombie children" and hooks. |
Looks like #1313 is the same issue as this one. |
Not sure if this issue is the root cause, but it seems React Native's FlatList Pull To Refresh functionality is broken because of the slightly delayed propagation of reducer value change compared to component's local setState. I created a minimal reproducible example below: you can see when using react-redux, Pull To Refresh feels shaky due to a slight delay of refreshing prop change after onRefresh. Edit: Link to snack is here (same code) https://snack.expo.io/ByN0nLBhS I wonder if this is related to the issue discussed here? |
I believe this might be related: visgl/deck.gl#4550 |
The issue I mentioned above does not appear if any of the following are used:
It does appear when:
So from what I can see, it seems that react-redux might have some issues with Zero Delays allowing other code to run between a dispatch and a rerender. |
with function component I managed to make it work by triggering a render of to sum up:
|
I'm going to close this as a WONTFIX for now, largely because we're encouraging folks to stop using If someone still feels strongly about this please comment, or even better file a PR to improve behavior here. |
What is the current behavior?
See the codesandbox link below for a running example of the following description.
I have a redux store containing a single array of integers,
elems
, initialized to[0]
. I have both anOuter
component and anInner
component which are parameterized byelems
viaconnect()
.Inner
stores an index into the array inthis.state.index
, initialized to0
. It also renders a button which, when clicked, will insert a new element into the redux and updatethis.state.index
to be the index of the new elem.When the button is pressed, the component is re-rendered twice. During the first re-render,
this.state.index
has changed, but notthis.props.elems
, so when I index the array, I receive anundefined
result. The subsequent re-render works fine, however.Note that if I remove the
Outer
component, and instead directly renderInner
, there is no issue. Something about having both a parent and a child component subscribed to the same redux data is causing this issue.If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to a CodeSandbox (https://codesandbox.io/s/new) or RN Snack (https://snack.expo.io/) example below:
https://codesandbox.io/s/eager-kepler-coo8g
What is the expected behavior?
I would expect
render()
to be called only once, with boththis.state
andthis.props
updated to their most recent values.Which versions of React, ReactDOM/React Native, Redux, and React Redux are you using? Which browser and OS are affected by this issue? Did this work in previous versions of React Redux?
See the codesandbox link above.
The text was updated successfully, but these errors were encountered: