comparação superficial é quando as propriedades dos objetos sendo comparados são feitas usando "===" ou igualdade estrita e não conduzirá comparações mais profundas nas propriedades. por exemplo
// 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.
Embora ambos os objetos pareçam ser iguais, game_item.teamsnão é a mesma referência que updated_game_item.teams. Para que 2 objetos sejam iguais, eles devem apontar para o mesmo objeto. Portanto, isso resulta no estado em avaliação para ser atualizado
// 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.
Desta vez, cada uma das propriedades retornam true para a comparação estrita, pois a propriedade teams no objeto novo e no antigo aponta para o mesmo objeto.
// 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
A updated_game_item3.first_world_cuppropriedade falha na avaliação estrita, pois 1930 é um número enquanto game_item.first_world_cupé uma string. Se a comparação tivesse sido solta (==), isso teria passado. No entanto, isso também resultará na atualização do estado.
Notas Adicionais:
- Fazer uma comparação profunda não tem sentido, pois afetaria significativamente o desempenho se o objeto de estado estivesse profundamente aninhado. Mas se não estiver muito aninhado e você ainda precisar de uma comparação profunda, implemente-o em shouldComponentUpdate e verifique se isso é suficiente.
- Você pode definitivamente transformar o objeto de estado diretamente, mas o estado dos componentes não seria afetado, uma vez que está no fluxo do método setState que reage implementa os ganchos do ciclo de atualização do componente. Se você atualizar o objeto de estado diretamente para evitar deliberadamente os ganchos do ciclo de vida do componente, provavelmente deverá usar uma variável ou objeto simples para armazenar os dados e não o objeto de estado.