Comments (8)
This happens because the mapStateToProps of the Item component is called with component props based on the previous store state.
Why do you say the previous state? I think they are called with the most recent state—and because the Item
s have not yet unmounted, they query state that doesn't exist anymore.
I don't think this is something we can fix. React state changes are asynchronous and React may (or may not) batch them. Therefore, the moment you press “Remove”, the Redux store updates, and both Item
and App
receive the new state. Even if the App
state change results in unmounting of Item
s, that will happen later than mapStateToProps
is called for Item
.
Unless I'm mistaken, there is nothing we can do. You have two options:
- Request all required state at
App
(or a lower, e.g.ItemList
) level and pass it down to “dumb”Item
s. - Add safeguards to
mapStateToProps
for “currently unmounting” state. For example, you may returnnull
fromrender
in this case.
Potentially we could have the component generated by connect()
return null
from its render
if mapStateToProps
returned null
. Does this make any sense? Is this too surprising?
from react-redux.
To whom who are looking for a workaround for this: An interesting observation is that if you do the selection in the component render method the issue is not present at all.
Example:
https://github.com/epeli/redux-connect-demo/pull/1/files
The down side is that your component will do more useless re-renders as you'll have to pass in data that is not actually used for rendering.
from react-redux.
Why do you say the previous state?
Because the store has been updated and the props App
has passed to the Item
are based on an old store state at the time the store query is run.
Therefore, the moment you press “Remove”, the Redux store updates, and both Item and App receive the new state.
Hmm. Is it actually required for the both to be subscribed to the store? Wouldn't it be enough if only the one most closest to the component root is subscribed? When that component renders it will trigger a render (and a store query) in all child components.
Seems like it would solve this. Although I have no idea how to detect the one closest to the root.
from react-redux.
Darn. Just realized it would break apps using pure components. Because the props between the parent and child components does not necessary change it might prevent some children from updating because React thinks there's nothing to the update but there might be because the store has changed.
from react-redux.
Potentially we could have the component generated by connect() return null from its render if mapStateToProps returned null. Does this make any sense? Is this too surprising?
I find it really counter intuitive that you have consider state transitions in the store query. This really feels a bug to me but I see how it's unresolvable with the current React APIs.
When thinking about the roots of this issue I think it can be nailed down to the fact that connect
can be used in a way to break the unidirectional data flow. It can inject new data to multiple points in the component tree and when you do that you will have a situation where you have some stale data between the tree nodes.
- Request all required state at App (or a lower, e.g. ItemList) level and pass it down to “dumb” Items.
This seems to be the right way to do it. Although I sometimes feel that I have to introduce new props to intermediate components just for them to passing those down. Which feels ugly. But I'm not sure it really is because it solves so many issues and weird edge cases like this.
Could Redux just prevent people from ending up with this situation? Maybe by removing ownProps
param from mapStateToProps
? It took me quite a while to figure out what the hell was going on.
from react-redux.
Could Redux just prevent people from ending up with this situation? Maybe by removing ownProps param from mapStateToProps? It took me quite a while to figure out what the hell was going on.
We removed it before, and people were unhappy. We do warn in the documentation that we encourage you to follow React flow and avoid connect()
ing leaf components.
from react-redux.
Heh, before today I would have been one those unhappy people but after pulling my hair out while debugging this today my opinion is certainly different. Sadly I missed that bit of the docs (or didn't take it seriously at the time ).
from react-redux.
Superseded by #99.
from react-redux.
Related Issues (20)
- Could not find react-redux context value; please ensure the component is wrapped in a <Provider> HOT 4
- Performance of useSyncExternalStore and React transitions HOT 5
- Disconnect from redux HOT 20
- Check why we no longer bail out of subscription checks when `store.getState()` hasn't changed HOT 1
- Rename `noopCheck` to `identityFunctionCheck` HOT 1
- Color visibility of some note HOT 5
- Unable to resolve module react-dom HOT 10
- Jest: Module import syntax error HOT 9
- Unable to resolve peer dependency react-native on [email protected] HOT 1
- TypeError: dispatcher.useSyncExternalStore is not a function HOT 1
- where development or production mode should be specified? HOT 7
- After some time useSelector stops doing re-renders HOT 8
- Provider properties for dev checks to be passed explicitly to new devModeChecks property HOT 7
- Getting Syntax error for react-redux when building project HOT 4
- Connect not working with detox envinronment HOT 1
- Getting issue in middleware of configureStore when update redux-toolkit to 2.0.1 HOT 1
- useDispatch() causing unexpected navigate back to previous screen HOT 3
- Single global store and two Provider occurs an error for microfrontend app HOT 1
- Test fail with provider in react-native HOT 3
- useSelector hook seems to break hook parsing in React Developer Tools HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-redux.