#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
бесполезное повторное отображение всего этого в целом. Но если у вас нет ashouldComponenentUpdate
для его дочерних элементов, при повторном отображенииRecordManager
вы также повторно отображаете все его дочерние элементы, даже если на самом деле изменился только один.
Ответ №1:
Это звучит как идеальный случай, который решается с помощью так называемого «чистого рендеринга»:
Вы можете неглубоко сравнивать реквизиты по мере их поступления, чтобы увидеть, изменились ли они
React предлагает дополнение для достижения этой цели:
https://facebook.github.io/react/docs/shallow-compare.html
Обновить
Теперь React предлагает вариант, называемый PureComponent, который выполняет работу по реализации shouldComponentUpdate
с неглубокой логикой сравнения.
Комментарии:
1. В итоге я поместил это на пару компонентов внутри
RecordManager
, и это значительно улучшило производительность. Спасибо!