Массивы и объекты вызывают ненужные повторные рендеры с Redux и Immutable.js - PullRequest
0 голосов
/ 18 января 2019

В моем проекте React у меня есть состояние Redux, которое имеет такую ​​форму:

{
  items: [{ ... },  { ... }, { ... }, ...]
  form: { 
    searchField: '',
    filter1: '',
    filter2: '',
  }
}

На одной странице есть компонент формы и компонент списка элементов. Я использую Immutable.js, поэтому каждый раз при обновлении поля формы создается новый массив items. Поскольку ссылка на массив теперь отличается, это приводит к повторному отображению списка элементов, даже если данные в массиве совпадают.

В моем компоненте списка я использую componentDidUpdate, чтобы поддерживать изменения в состоянии журнала, чтобы подтвердить, что обновленный массив вызывает повторную визуализацию:

componentDidUpdate(prevProps) {
  Object.keys(prevProps).forEach((key) => {
    if (prevProps[key] !== this.props[key]) {
      console.log('changed prop:', key, 'from', this.props[key], 'to', prevProps[key]);
    }
  });
}

Массивы from и to, которые регистрируются, содержат все те же самые данные.

Как я могу предотвратить эти ненужные повторные рендеры?

Единственное, о чем я могу думать, это то, что в shouldComponentUpdate компонента списка, переберите массив и сравните идентификаторы элементов с nextProps. Однако это кажется неэффективным.

Вот мой редуктор

import Immutable from 'immutable';
import { types } from '../actions';

const initialState = {
  items: []
  form: { 
    searchField: '',
    filter1: '',
    filter2: '',
  }
}

export default function reducer(_state = initialState, action) {
  const state = Immutable.fromJS(_state);

  switch (action.type) {
    case types.HANDLE_FORM_CHANGE:
      return state.setIn(['form', action.field], action.value).toJS();
    default:
      return _state;
  }
}

1 Ответ

0 голосов
/ 18 января 2019

Подход shouldComponentUpdate - это способ, которым я обращался с этим / видел, как другие справляются с этим.

Обратите внимание, что вам не нужно вручную циклически перебирать вашу коллекцию и сравнивать идентификаторы, так как Immutable включает метод is для сравнения коллекций:

Проверка на равенство значений с семантикой, аналогичной Object.is, но обрабатывает Неизменные Коллекции как ценности, равные, если вторая Коллекция включает эквивалентные значения.

Очевидно, это предполагает, что состояние, передаваемое вашим компонентам, является Неизменяемыми объектами, которые, как я понимаю, считаются чем-то вроде лучшей практики (см. Используйте неизменяемые везде, кроме ваших тупых компонентов ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...