React-redux rerenders when creating arrays

两盒软妹~` 提交于 2019-12-10 22:46:52

问题


I have a connected component where I would like to retrieve an array of objects. In my store, there is an array of ids, and an object where I keep the items like this:

const state = {
  items: [0, 1, 2],
  itemsById: {
    0: {},
    1: {},
    2: {},
  },
}

So using the connect function of react-redux, I do this in my component to inject the correct array:

const mapStateToProps = (state) => ({
  items: state.items.map((itemId) => state.itemsById[itemId]),
})

My app triggers updates very often (I dispatch actions in requestAnimationFrame), but the items array do not change during the process. By analyzing the app with the React Perf addon, it seems that my connected component makes unnecessary rendering, and I don't understand why because the items in the state don't change.

I already tried to make a memoized selector using reselect but it seems it does not change anything.

Update (solution)

It works when you use a selector created with reselect. My problem was in the selector itself: my items array is located in a parent object which updates very frequently, and I was selecting this object instead of selecting the items array directly.

Don't do this:

const parentSelector = (state) => state.parent
const itemsByIdSelector = (state) => state.itemsById
const selector = createSelector(
  parentSelector,
  itemsByIdSelector,
  (parent, itemsById) => parent.items.map(...)
)

Do this:

const itemsSelector = (state) => state.items
const itemsByIdSelector = (state) => state.itemsById
const selector = createSelector(
  itemsSelector,
  itemsByIdSelector,
  (items, itemsById) => items.map(...)
)

回答1:


You are creating a new array every time connect is called by doing this:

const mapStateToProps = (state) => ({
  items: state.items.map((itemId) => state.itemsById[itemId]),
})

To prevent that use a memoized selector, which will return the same array every time, unless something actually changed. A selector is a method that computes the derived data from the state. Reselect is a memoized selector library for redux.



来源:https://stackoverflow.com/questions/39062188/react-redux-rerenders-when-creating-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!