5

The current approach is to connect whole book list into Book List Component. However, it is not an efficient to render huge components by changing only several fields in state. I dont know how to map each book component connect to each individual Book state.

The project is using redux. The application global state like this

{
  "books": [
    {
      "field1": "field1",
      "field2": "field2",
      "field3": "field3",
    } ...
  ]
}

In the Book List component, we connect list with it by using react redux

export default connect(state => ({
  books: state.books
}))(BookListComponent);

Now the requirement changes, fields in book will not be changed frequently. The issue is, if one field is changed, it will update the whole BookListComponent. That is not performant component I am expecting.

I would like to push connect logic down to individual Book Component in order to use reselect

The state doesnt have index of the book, I dont know how to write connect to make it work

export default connect(state => ({
  books[index]: state.books[index]
}))(BookListComponent);

Thanks for advance and all options are welcome

Xiaohe Dong
  • 4,953
  • 6
  • 24
  • 53
  • 1
    If you render your books list with a `key` prop, you don't need to worry very much. Your items will be tracked and accordingly updated. Then you can also write `shouldComponentUpdate` function for the `Book` component, to tell, when a book should not be re-rendered. – just-boris Feb 27 '17 at 14:09

3 Answers3

3

Your second example is almost correct. A mapState function can be declared to take two parameters instead of one. If two parameters are declared, Redux will call that mapState function with the props that were given to the wrapper component. So, the mapState function for a list item would be:

const mapState = (state, ownProps) => {
    const book = state.books[ownProps.index];
    return {book}
}

My blog post Practical Redux, Part 6: Connected Lists, Forms, and Performance shows some examples of how to do that, and also discusses the key considerations for application performance in Redux.

markerikson
  • 63,178
  • 10
  • 141
  • 157
  • But then in the reducer you still must return a new array correct? And what if this array is nested? e.g. `{ books: [], CDs: [] }` ? – Erez Cohen Feb 19 '18 at 14:36
  • If you're going to update nested data, you need to make copies of _all_ levels of nesting when you do updates. See the [Immutable Update Patterns](https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns) section in the Redux docs for examples. – markerikson Feb 19 '18 at 16:34
0

You can connect any component you like. There is no hard and fast rule that you can only connect top level components.

While there is a performance hit to connecting top level components and passing the props down I have not witnessed it have a noticeable detrimental effect. The benefit in being able to trace the data through the code is always worth it in my opinion. There is a discussion on it here.

spirift
  • 2,994
  • 1
  • 13
  • 18
0

React updates only changed fields

While it's true that render function is called each time you update a book, that doesn't mean that the whole list is re-rendered.

Remember, that in React we are using Virtual DOM. It allows us to update only the elements that are actually changed.

Take a look at this article (it's short and has working code example on codeopen) https://facebook.github.io/react/docs/rendering-elements.html and this one (a little more detailed) https://facebook.github.io/react/docs/state-and-lifecycle.html

If you have read those articles, you know that all you need is to inspect your app and see what is actually rendered at each change.

Community
  • 1
  • 1
Mycolaos
  • 74
  • 1
  • 5