question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

connect(mapStateToProps) is executed with component props based on the previous state

See original GitHub issue

Ok, 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:closed
  • Created 8 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

6reactions
esamattiscommented, Sep 8, 2015

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.

5reactions
gaearoncommented, Sep 2, 2015

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 Items 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 Items, that will happen later than mapStateToProps is called for Item.

Unless I’m mistaken, there is nothing we can do. You have two options:

  1. Request all required state at App (or a lower, e.g. ItemList) level and pass it down to “dumb” Items.
  2. Add safeguards to mapStateToProps for “currently unmounting” state. For example, you may return null from render 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?

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found