Перерисовать проблемы с производительностью — где реализовать shouldComponentUpdate?

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня возникли проблемы с решением, куда добавить shouldComponentUpdate метод. Изображение ниже должно дать достаточное представление о структуре моей страницы:

введите описание изображения здесь

Проблема в том, что всякий раз, когда я ввожу TextField (контролируемое поле), обновление состояния приводит RecordManager к повторному отображению всего. И если есть более 50 Record элементов, это, очевидно, огромный удар по производительности.

Я временно решил эту проблему, добавив следующий метод в RecordManager :

   shouldComponentUpdate(nextProps, nextState) {
    return this.state.newRecordName === nextState.newRecordName;
  }
  

Соответствующие TextField :

   <TextField
    style={styles.textField}
    id="newRecordName"
    hintText={newRecordHintText}
    onChange={this.recordNameChange}
    onKeyDown={this.recordNameKeyDown}
  />
  

Мое решение кажется немного взломом. Не лучше ли поместить компонент shouldComponentUpdate в Record компонент? Хотя тогда, похоже, мне придется проверять целую кучу разных случаев, например:

 shouldComponentUpdate(nextProps, nextState) {
  if (this.props.ratings !== nextProps.ratings) return true;
  if (this.props.updatedAt !== nextProps.updatedAt) return true;
  // potentially 3-4 more fields
  return false;
}
  

Какое идеальное решение здесь?

По запросу ниже, другой соответствующий код в RecordManager :

   recordNameChange = ({ target }) => {
    this.setState({ newRecordName: target.value });
  };

  recordNameKeyDown = (event) => {
    const keyCode = keycode(event);

    if (keyCode === 'enter') {
      this.addRecord();
    } else if (keyCode === 'esc') {
      this.cancelAddRecord();
    }
  };
  

RecordManager состояние:

 this.state = {
  dialogMessage: '',
  newRecordName: '',
  viewMode: localStorage.getItem('userSettingsViewMode') ||
    viewModes.LIST,
};
  

Комментарии:

1. Используя ваше решение, все ваши Record s все равно будут повторно отображаться при каждом изменении одного из них. Теоретически вам нужен только тот, который был изменен для повторного отображения. Так что на самом деле ваше решение не является взломом, а скорее, я не думаю, что вы действительно решили свою проблему с производительностью.

2. Можете ли вы предоставить содержимое this.recordNameChange и recordNameKeyDown , возможно, образец вашего RecordManager.state ? Мне трудно понять, как работает ваша первая shouldComponentUpdate работа.

3. @Roque Не соответствует React DevTools. С моим решением для взлома, когда я печатаю, Record s не перерисовываются. Это была проблема, которую я пытался решить, и она сработала.

4. Конечно, я обновлю свой пост через несколько.

5. Если я не ошибаюсь, все ваши записи включены в ваш RecordManager . Ваш первый shouldComponentUPdate предотвращает RecordMananager бесполезное повторное отображение всего этого в целом. Но если у вас нет a shouldComponenentUpdate для его дочерних элементов, при повторном отображении RecordManager вы также повторно отображаете все его дочерние элементы, даже если на самом деле изменился только один.

Ответ №1:

Это звучит как идеальный случай, который решается с помощью так называемого «чистого рендеринга»:

Вы можете неглубоко сравнивать реквизиты по мере их поступления, чтобы увидеть, изменились ли они

React предлагает дополнение для достижения этой цели:

https://facebook.github.io/react/docs/shallow-compare.html


Обновить

Теперь React предлагает вариант, называемый PureComponent, который выполняет работу по реализации shouldComponentUpdate с неглубокой логикой сравнения.

Комментарии:

1. В итоге я поместил это на пару компонентов внутри RecordManager , и это значительно улучшило производительность. Спасибо!