Ререндеринг React-redux при создании массивов

У меня есть подключенный компонент, где я хотел бы получить массив объектов. В моем магазине есть массив идентификаторов и объект, в котором я храню такие предметы:

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

Поэтому, используя функцию connect react-redux, я делаю это в своем компоненте, чтобы ввести правильный массив:

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

Мое приложение запускает обновления очень часто (я отправляю действия в requestAnimationFrame), но массив items не меняется в процессе. Анализируя приложение с надстройкой React Perf, кажется, что мой подключенный компонент делает ненужный рендеринг, и я не понимаю, почему, потому что items в состоянии не меняется.

Я уже пытался сделать мемоизированный селектор с помощью повторного выбора, но, похоже, это ничего не меняет.

Обновление (решение)

Это работает, когда вы используете селектор, созданный с помощью повторного выбора. Моя проблема заключалась в самом селекторе: мой массив items расположен в родительском объекте, который очень часто обновляется, и я выбирал этот объект вместо того, чтобы напрямую выбирать массив items.

Не делайте этого:

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

Сделай это:

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

person Anthony Dugois    schedule 21.08.2016    source источник


Ответы (1)


Вы создаете новый массив каждый раз, когда вызывается соединение, делая это:

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

Чтобы предотвратить это, используйте запоминаемый селектор, который каждый раз будет возвращать один и тот же массив, если что-то действительно изменилось. Селектор — это метод, который вычисляет производные данные из состояния. Reselect — это мемоизированная библиотека селекторов для редукции.

person Ori Drori    schedule 21.08.2016