connect(mapStateToProps) is executed with component props based on the previous state
See original GitHub issueOk, this is really hard to explain so I’ve set up an example here:
https://github.com/epeli/redux-connect-demo
Build it and play with it with devtools console opened. You should see following errors:
Uncaught TypeError: Cannot read property 'foo' of undefined
This happens because the mapStateToProps
of the Item
component is called with component props based on the previous store state. The two states are not compatible anymore and it causes all kinds of errors.
I think the parent should render and update the props for the Item
component before the mapStateToProps
of the Item
component can be executed.
Issue Analytics
- State:
- Created 8 years ago
- Comments:8 (8 by maintainers)
Top Results From Across the Web
Connect: Extracting Data with mapStateToProps - React Redux
It should take a first argument called state , optionally a second argument called ownProps , and return a plain object containing the...
Read more >React Redux connect(): When and how to use it
Using mapStateToProps in React Redux; Default implementation; Passing an object ... components based on their connection to the Redux store.
Read more >reactjs - React Redux - Why mapStateToProps is called before ...
It is done by connect which is a Higher Order Component that executes mapStateToProps before your component is initialised.
Read more >A Redux performance obsession: mapping state to props
When connect is running it's internal shouldComponentUpdate, it looks at the incoming result of mapStateToProps and compares each value in the ...
Read more >Hooks | React Redux
The selector is approximately equivalent to the mapStateToProps argument to connect conceptually. The selector will be called with the entire Redux store state...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
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.
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
andApp
receive the new state. Even if theApp
state change results in unmounting ofItem
s, that will happen later thanmapStateToProps
is called forItem
.Unless I’m mistaken, there is nothing we can do. You have two options:
App
(or a lower, e.g.ItemList
) level and pass it down to “dumb”Item
s.mapStateToProps
for “currently unmounting” state. For example, you may returnnull
fromrender
in this case.Potentially we could have the component generated by
connect()
returnnull
from itsrender
ifmapStateToProps
returnednull
. Does this make any sense? Is this too surprising?