#javascript #reactjs
#javascript #reactjs
Вопрос:
Я читал следующую статью о React.memo https://blog.bitsrc.io/optimize-your-react-app-with-react-memo-ec52447b09ba
У меня было 2 конкретных вопроса по статье.
- Согласно ссылке, в нем говорится: «В функциональных компонентах React по умолчанию выполняет только две оптимизации. Во-первых, это позволяет избежать процесса повторного рендеринга, если при поверхностном сравнении новое состояние равно старому состоянию. Во-вторых, он обновляет только узлы DOM, которые были изменены, а не весь DOM, поскольку обновление DOM является дорогостоящим «.
Я был смущен, когда он сказал, что реагирует по умолчанию, сравнивает состояние. Я понимаю, что это происходит только в том случае, если мы используем React.memo. Я что-то здесь упускаю?
- В соответствии с примером неглубокого сравнения, показанным на сайте, он, по-видимому, предполагает различное поведение для объектов в массивах. Не уверен, что это тоже правильно. Я думал, что оба массива / объекта будут получать новую ссылку каждый раз, и, следовательно, поверхностное сравнение будет возвращать false каждый раз для них?
В частности, этот пример по ссылке меня смутил;
const car1 = {
color: 'red',
model: 'S',
};
const car2 = {
color: 'red',
model: 'X',
};
const car3 = {
color: 'red',
model: 'S',
};
shallowCompare(car1, car2); // false
shallowCompare(car1, car3); // true - Why would this return true ???
const arr1 = [1];
const arr2 = [1];
const arr3 = arr1;
console.log(arr1 === arr2); // false - Why is this different compared to object behavior ?
console.log(arr1 === arr3); // true
Кроме того, с моей стороны я попытался использовать приведенную ниже пользовательскую функцию для неглубокого сравнения и заметил, что и объект, и массив ведут себя аналогично. Эта функция не является частью ссылки на статью выше.
function areEqualShallow(a, b) {
for(var key in a) {
if(!(key in b) || a[key] !== b[key]) {
return false;
}
}
for(var key in b) {
if(!(key in a) || a[key] !== b[key]) {
return false;
}
}
return true;
}
Комментарии:
1. «Реагирует по умолчанию, сравнивает состояние» — это происходит при обновлении состояния. Реакция сравнивает старое состояние с новым и повторно отображает компонент, если поверхностное сравнение возвращает false .
2. На сколько вопросов вы ищете ответы? Я запутался в истории, вы спрашиваете: 1. «Я был смущен, когда он говорит, что реагирует по умолчанию, сравнивает состояние. Я понимаю, что это происходит только в том случае, если мы используем React.memo», 2. «Я думал, что оба массива / объекта будут получать новую ссылку каждый раз, и, следовательно, поверхностное сравнение будет возвращать false каждый раз для них?» ? Можете ли вы быть более конкретными в отношении того, что вы спрашиваете
3. Если вы внимательно прочитаете вопрос, вы поймете мои конкретные вопросы!!
4. Я прочитал это три раза, ну, я попробую угадать
Ответ №1:
Начнем с того, что наиболее надежным источником является то, что опубликовано командой React.
Я был смущен, когда он сказал, что реагирует по умолчанию, сравнивает состояние. Я понимаю, что это происходит только в том случае, если мы используем React.memo. Я что-то здесь упускаю?
Это правда, вы не можете настроить способ сравнения состояний в React.
Хотя существуют обходные пути, они не учитывают «по умолчанию», например, путем сохранения предыдущего состояния в ссылке и условного изменения состояния с его помощью:
useEffect(() => {
if (areEqualCustom(prevState.current, newState)) {
setState(newState);
prevState.current = newState;
}
}, [newState]);
В соответствии с примером неглубокого сравнения, показанным на сайте, он, по-видимому, предполагает различное поведение для объектов в массивах. Не уверен, что это тоже правильно. Я думал, что оба массива / объекта будут получать новую ссылку каждый раз, и, следовательно, поверхностное сравнение будет возвращать false каждый раз для них?
Вы правы, определение автора для «поверхностного сравнения» неверно, потому что «поверхностное сравнение» определяется оператором строгого равенства ( ===
) .
// Blog example
const car1 = {
color: 'red',
model: 'S',
};
const car3 = {
color: 'red',
model: 'S',
};
// car1 === car3
shallowCompare(car1, car3) // always false
// React example
const onClick = () => {
// Don't mutate state in React.
stateObject.x = 5;
// prevState === stateObject (true)
setState(stateObject); // no render
// Instead use Object.assign / shallow copy
setState({ ...stateObject, x: 5 }); // always render
};
Обратите внимание, что в последнем примере, даже если предыдущее состояние и текущее состояние полностью равны, оно все равно будет повторным.
setState({ x: 5 }); // always render
// even if prevState = { x: 5 }
[1] === [1]
Почему это отличается от поведения объекта?
Это не так, это то же самое поведение.