Dalam dokumentasi React ini, disebutkan bahwa
shallowCompare melakukan pemeriksaan kesetaraan dangkal pada properti saat ini dan objek nextProps serta status saat ini dan objek nextState.
Hal yang tidak dapat saya pahami adalah Jika membandingkan objek secara dangkal maka metode shouldComponentUpdate akan selalu mengembalikan nilai true, karena
Kita seharusnya tidak mengubah negara bagian.
dan jika kita tidak memutasi statusnya maka perbandingan akan selalu mengembalikan false dan pembaruan shouldComponent akan selalu mengembalikan nilai true. Saya bingung tentang cara kerjanya dan bagaimana kita akan menimpanya untuk meningkatkan kinerja.
sumber
Perbandingan dangkal adalah ketika properti dari objek yang dibandingkan dilakukan menggunakan "===" atau persamaan yang ketat dan tidak akan melakukan perbandingan lebih dalam ke properti. untuk mis
// 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.
Meskipun kedua objek tampak sama,
game_item.teams
referensi ini tidak sama denganupdated_game_item.teams
. Agar 2 objek menjadi sama, mereka harus menunjuk ke objek yang sama. Dengan demikian ini menghasilkan status yang sedang dievaluasi untuk diperbarui// 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.
Kali ini setiap properti mengembalikan nilai true untuk perbandingan yang ketat karena properti tim di objek baru dan lama mengarah ke objek yang sama.
// 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
The
updated_game_item3.first_world_cup
properti gagal evaluasi yang ketat seperti 1930 adalah angka sementaragame_item.first_world_cup
adalah string. Jika perbandingannya longgar (==) ini akan berlalu. Meskipun demikian ini juga akan menghasilkan pembaruan status.Catatan tambahan:
sumber
prevObj
berisi kunci yangnewObj
tidak memiliki, pembandingan akan gagal.sumber
Ada juga penjelasan warisan tentang shallow bandingkan di React:
UPD : Dokumentasi saat ini mengatakan tentang perbandingan dangkal:
UPD2: Menurut saya rekonsiliasi juga merupakan tema penting untuk dangkal membandingkan pemahaman.
sumber
and returning true when the values
Cuplikan dangkal yang sama oleh @supi di atas ( https://stackoverflow.com/a/51343585/800608 ) gagal jika
prevObj
memiliki kunci yangnewObj
tidak memilikinya. Berikut adalah implementasi yang harus memperhitungkannya:const shallowEqual = (objA, objB) => { if (!objA || !objB) { return objA === objB } return !Boolean( Object .keys(Object.assign({}, objA, objB)) .find((key) => objA[key] !== objB[key]) ) }
Perhatikan bahwa hal di atas tidak berfungsi di Explorer tanpa polyfill.
sumber
Ada implementasi dengan contoh.
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
sumber