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.

Question: ownProps in mapStateToProps

See original GitHub issue

I’ve read the docs about the ownProps argument, and I think I may be misusing it.

Could you use this ownProps to connect() dynamically created components?

I have a giant table. Number of columns/rows depend on what I get back from the server. The state is an array of objects, each representing a row, and each row is component I’m trying to connect(). The app updates as intended when I use state and does not when I use ownProp.

// Row.jsx 
// first row example, row doesn't update when using ownProps
function mapStateToProps(state, ownProps) {
  return {
    rowData: ownProps.row,
  };
}
// Row.jsx
// first row example, row updates when using state
function mapStateToProps(state, ownProps) {
  return {
    rowData: state.table.rows[0],
  };
}

I’m guessing it has to do something with ownProps being a copy and not a reference to state?

state.table.rows[0] === ownProps.row // false

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

12reactions
gaearoncommented, Jan 24, 2016

I think you got a bit confused. I’m not sure why you’re doing it this way.

Todo used to be a purely presentational component. You changed it to be a container generated by connect(). Why? Now it accepts some todo props from its parent but also connects to the store. I don’t understand why you needed a connect() there. Moreover connect() is only needed if you want to subscribe component to the store updates. It doesn’t make sense to use connect() and only use ownProps to pass a prop down. It’s received from parent anyway. You’re subscribing to the store by using connect() but rather than use store’s state, just pass down one of ownProps which Todo receives from a parent component. Effectively it does nothing at all: since you’re not using store state inside mapStateToProps() you can as well completely remove it and the connect() call, and behavior won’t change. So I don’t understand what you were trying to do there.

The redrawing problem happens because you removed connect() from the generated VisibleTodoList and wrote it by hand. You are using getState() inside but you forgot to subscribe to the store to force updates when store state changes. This is why VisibleTodoList renders once with the initial state and isn’t aware that you are toggling todos—it’s not subscribed! To fix this you can add a store subscribe() call in componentDidMount() and call forceUpdate() when store state changes. However this is only meant as a learning exercise. It’s a lot less efficient than using connect() which has many performance optimizations. So I encourage you to use connect() instead of subscribing to the store by hand.

If some of this is unclear I suggest you to take another look at all React videos in the course. I only show how to write container components by hand as part of the explanation build up. So you understand what connect() does under the hood. I don’t actually advise you to write subscription code by hand in any real apps. Use connect(). I also don’t recommend to use connect() when component receives store data by props—it is useless in this case.

Hope it helps.

5reactions
gaearoncommented, Jan 24, 2016

If you want to do that you can change VisibleTodoList to only select todo IDs from the store in its mapStateToProps. Then you can change TodoList to accept todoIds array rather than todos array as a prop. Then you can change TodoList to pass id as a prop to Todo component rather than {…todo}. Finally, then you can change mapStateToProps for Todo to return something like state.todos.find(todo => todo.id === ownProps.id).

However this won’t be very efficient either for the reason that todos are kept in an array so every lookup is expensive. It’s better to store them in an object keyed by todo ID and have a separate array of IDs in the state. Then you can use something like state.todosById[ownProps.id] in mapStateToProps of Todo.

Hope that helps! I would still start by adding shouldComponentUpdate() implementation to Todo component rather than connect() every individual Todo. You can use react-addons-shallow-compare for this. There is no guarantee that connecting every individual Todo is going to significantly improve your performance—implementing shouldComponentUpdate() is more likely to help.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is the use of the ownProps arg in mapStateToProps and ...
I see that the mapStateToProps and mapDispatchToProps function which are passed to the connect function in Redux take ownProps as a second ...
Read more >
Connect: Extracting Data with mapStateToProps - React Redux
mapStateToProps should be defined as a function: function mapStateToProps(state, ownProps?) ... It should take a first argument called state , ...
Read more >
3 ways to test mapStateToProps and mapDispatchToProps
To demonstrate, I created a simple Dice component that we can roll to dispatch actions. import React from 'react'; import PropTypes ...
Read more >
connectFlux function - over_react_flux library - Dart API
mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It is called every time...
Read more >
Mastering mergeProps in Redux - Peanut Butter JavaScript
You use mapStateToProps to pass parts of the state to the component ... ownProps – which contains all of the props passed into...
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