-
-
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
Child may render with new state before parent #1589
Comments
For now we were able to workaround this by moving the React Redux Before:
After:
This way, when the context consumer is re-rendered due to context changes, the previous connected props will be re-used. https://stackblitz.com/edit/react-redux-and-context-renders-test-hvhqwv?file=index.tsx |
Yeah, isn't this basically the same thing as #1510 ? |
The same root cause, yeah! I just didn't realise it could result in discrepancies like this when used in specific scenarios such as when using React context, so I filed it as a separate issue. (Maybe it will also make the issue easier for someone to find if they are also running into this.) I think this puts more emphasis on fixing #1510. What do you think? |
I don't think the issue is "fixable" in v7 given our current architecture. I'd be happy to be proven wrong, and if anyone has any concrete suggestions on how we can do that, I'm absolutely interested. I just don't see how it's avoidable given the way we trigger nested subscriptions. Looking forward, it's likely that React-Redux v8 will be based around use of I don't yet know enough about how that implementation might look to predict whether or not RRv8 would still have these issues. I think that |
Thanks for your insightful answer. It's going to take awhile for those bits to register in my head!
https://stackblitz.com/edit/react-redux-and-context-renders-test-ng6tpb?file=index.tsx (I also had to add The issue doesn't occur with this example. So when using the hook, nested updates are batched (unlike when using |
Both The difference is that This is good for ensuring the "components never recalculate or render with stale props" invariant, but obviously has the edge cases we've seen here and in #1510.
This is good for ensuring that there's fewer individual commits and avoiding the edge case here, but runs into the stale props issue because nested use of hooks will triggering updates before the component has received updated props from its parent. |
Very interesting, thank you so much for explaining that. |
This works for class component. How would one fix it when using functional components? |
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?
Full reduced test case: https://github.com/OliverJAsh/react-redux-and-context-renders-test
Same reduced test case in the form of a StackBlitz: https://stackblitz.com/edit/react-redux-and-context-renders-test?file=index.tsx
The example might look contrived but it's based on real world code that is in production on Unsplash. Apologies in advance that I couldn't provide a simpler example—this is the smallest reduced test case I was able to find.
The simplified component tree looks something like this:
The child component
Item
is rendered with new Redux state (windowWidth
) before its parent,Grid
. We can see this from the logs I added to component render functions:What I expect: the child component
Item
should not be rendered with the new Redux state before its parent,Grid
.The issue seems to occur when React re-renders due to simultaneous changes to context and Redux state.
From my understanding, this is what's happening:
Item
is subscribed to both the context value and Redux state.componentDidMount
).GridWrapper
with the new state. At the same time, React will re-render context consumers with the new context value.Item
is inside of a context consumer so it will re-render, but incidentally this will also mean it will use the new Redux state, even though React Redux hasn't told it to.Grid
with the new state.As I understand it, the only way to avoid this problem would be to fix #1510 so that nested updates at different levels are batched.
What is the expected behavior?
See above.
Which versions of React, ReactDOM/React Native, Redux, and React Redux are you using?
The latest versions of everything, at the time of writing.
Which browser and OS are affected by this issue?
All.
Did this work in previous versions of React Redux?
I'm not sure.
The text was updated successfully, but these errors were encountered: