La comparaison superficielle se produit lorsque les propriétés des objets comparés sont effectuées en utilisant "===" ou une égalité stricte et ne conduisent pas de comparaisons plus profondément dans les propriétés. par exemple
// 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.
Bien que les deux objets semblent être identiques, ce game_item.teams
n'est pas la même référence que updated_game_item.teams
. Pour que 2 objets soient identiques, ils doivent pointer vers le même objet. Il en résulte que l'état évalué doit être mis à jour
// 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.
Cette fois, toutes les propriétés renvoient true pour la comparaison stricte, car la propriété teams dans le nouvel et l'ancien objet pointe vers le même objet.
// 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
La updated_game_item3.first_world_cup
propriété échoue à l'évaluation stricte car 1930 est un nombre tandis que game_item.first_world_cup
est une chaîne. Si la comparaison avait été lâche (==), cela aurait passé. Néanmoins, cela entraînera également une mise à jour de l'état.
Notes complémentaires:
- Faire une comparaison approfondie est inutile car cela affecterait considérablement les performances si l'objet d'état était profondément imbriqué. Mais si ce n'est pas trop imbriqué et que vous avez toujours besoin d'une comparaison approfondie, implémentez-le dans shouldComponentUpdate et vérifiez si cela suffit.
- Vous pouvez certainement muter directement l'objet d'état, mais l'état des composants ne serait pas affecté, car il se trouve dans le flux de méthode setState qui réagit implémente les hooks du cycle de mise à jour des composants. Si vous mettez à jour l'objet d'état directement pour éviter délibérément les hooks de cycle de vie des composants, vous devriez probablement utiliser une simple variable ou un objet pour stocker les données et non l'objet d'état.