В этой документации React сказано, что
shallowCompare выполняет поверхностную проверку равенства для текущих объектов props и nextProps, а также для объектов текущего состояния и nextState.
Я не могу понять, что если он неглубоко сравнивает объекты, тогда метод shouldComponentUpdate всегда будет возвращать true, так как
Мы не должны изменять состояния.
и если мы не изменяем состояния, то сравнение всегда будет возвращать false, и поэтому обновление shouldComponent всегда будет возвращать true. Я не понимаю, как это работает, и как мы переопределим это, чтобы повысить производительность.
источник
поверхностное сравнение - это когда свойства сравниваемых объектов выполняются с использованием «===» или строгого равенства и не будут проводить более глубокое сравнение свойств. например, для
// a simple implementation of the shallowCompare. // only compares the first level properties and hence shallow. // state updates(theoretically) if this function returns true. function shallowCompare(newObj, prevObj){ for (key in newObj){ if(newObj[key] !== prevObj[key]) return true; } return false; } // var game_item = { game: "football", first_world_cup: "1930", teams: { North_America: 1, South_America: 4, Europe: 8 } } // Case 1: // if this be the object passed to setState var updated_game_item1 = { game: "football", first_world_cup: "1930", teams: { North_America: 1, South_America: 4, Europe: 8 } } shallowCompare(updated_game_item1, game_item); // true - meaning the state // will update.
Хотя оба объекта кажутся одинаковыми,
game_item.teams
это не та же ссылка, что иupdated_game_item.teams
. Чтобы два объекта были одинаковыми, они должны указывать на один и тот же объект. Таким образом, это приводит к тому, что состояние оценивается как обновляемое.// Case 2: // if this be the object passed to setState var updated_game_item2 = { game: "football", first_world_cup: "1930", teams: game_item.teams } shallowCompare(updated_game_item2, game_item); // false - meaning the state // will not update.
На этот раз каждое из свойств возвращает true для строгого сравнения, поскольку свойство team в новом и старом объекте указывает на один и тот же объект.
// Case 3: // if this be the object passed to setState var updated_game_item3 = { first_world_cup: 1930 } shallowCompare(updated_game_item3, game_item); // true - will update
updated_game_item3.first_world_cup
Свойство нарушается строгая оценка в 1930 это число , аgame_item.first_world_cup
строка. Если бы сравнение было слабым (==), это прошло бы. Тем не менее, это также приведет к обновлению состояния.Дополнительные примечания:
источник
prevObj
содержит ключ,newObj
которого нет, сравнение не удастся.источник
Существует также устаревшее объяснение неглубокого сравнения в React:
UPD : Текущая документация говорит о неглубоком сравнении:
UPD2: Я думаю , что сверка также важная тема для неглубокого сравнения понимания.
источник
and returning true when the values
Неглубокий равный фрагмент от @supi выше ( https://stackoverflow.com/a/51343585/800608 ) не работает, если
prevObj
есть ключ,newObj
которого нет. Вот реализация, которая должна это учитывать:const shallowEqual = (objA, objB) => { if (!objA || !objB) { return objA === objB } return !Boolean( Object .keys(Object.assign({}, objA, objB)) .find((key) => objA[key] !== objB[key]) ) }
Обратите внимание, что это не работает в проводнике без полифиллов.
источник
Есть реализация с примерами.
const isObject = value => typeof value === 'object' && value !== null; const compareObjects = (A, B) => { const keysA = Object.keys(A); const keysB = Object.keys(B); if (keysA.length !== keysB.length) { return false; } return !keysA.some(key => !B.hasOwnProperty(key) || A[key] !== B[key]); }; const shallowEqual = (A, B) => { if (A === B) { return true; } if ([A, B].every(Number.isNaN)) { return true; } if (![A, B].every(isObject)) { return false; } return compareObjects(A, B); }; const a = { field: 1 }; const b = { field: 2 }; const c = { field: { field: 1 } }; const d = { field: { field: 1 } }; console.log(shallowEqual(1, 1)); // true console.log(shallowEqual(1, 2)); // false console.log(shallowEqual(null, null)); // true console.log(shallowEqual(NaN, NaN)); // true console.log(shallowEqual([], [])); // true console.log(shallowEqual([1], [2])); // false console.log(shallowEqual({}, {})); // true console.log(shallowEqual({}, a)); // false console.log(shallowEqual(a, b)); // false console.log(shallowEqual(a, c)); // false console.log(shallowEqual(c, d)); // false
источник