J'ai 2 structures imbriquées newState et newState1 .
Mais quand je compare leurs, equals () ou Immutable.is () a retourné false . Les valeurs dans ces structures sont identiques.
Comment comparer correctement newState et newState1 ?
var grid = {
editable: false,
widgets: [{
name: 'Some widget',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}, {
name: 'Some widget1',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}]
};
var state = Immutable.fromJS(grid);
var newState = state.updateIn(['widgets'], function (list) {
return list.Push(Immutable.Map({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
var newState1 = state.updateIn(['widgets'], function (list) {
return list.Push(Immutable.Map({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
console.log(state.toJS(), newState.toJS(), newState1.toJS());
console.log(newState.equals(newState1)); //false
Code dans JSFiddle: https://jsfiddle.net/z3xuagwm/
Il semble que immutablejs ne fait pas de conversion profonde, donc si votre valeur est object, elle reste objet.
Lorsque vous créez un objet différent à chaque étape de la mise à jour, ces objets étant traités différemment, vous devez également le convertir en objet Immutable.Map pour que la comparaison soit vraie.
// Primitives.
var test1 = Immutable.Map({
a: 'a',
b: 'b',
c: 'c'
});
var test2 = Immutable.Map({
a: 'a',
b: 'b',
c: 'c'
});
console.log('Test primitive', test1.equals(test2)); // true
// Object
test1 = Immutable.Map({
a: 'a',
b: 'b',
c: {}
});
test2 = Immutable.Map({
a: 'a',
b: 'b',
c: {}
});
console.log('Test object', test1.equals(test2)); // false
// Its because
var a = {};
var b = {};
console.log('a === b?', a === b); // false
// Convert
test1 = Immutable.Map({
a: 'a',
b: 'b',
c: Immutable.Map({})
});
test2 = Immutable.Map({
a: 'a',
b: 'b',
c: Immutable.Map({})
});
console.log('Test converted', test1.equals(test2)); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.5/immutable.min.js"></script>
Changez Immutable.Map en Immutable.fromJS dans vos fonctions Push (comme cela a été mentionné - seul fromJS effectuera une conversion en profondeur. Map, List, etc. ne le fera pas):
var newState = state.updateIn(['widgets'], function (list) {
return list.Push(Immutable.fromJS({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
var newState1 = state.updateIn(['widgets'], function (list) {
return list.Push(Immutable.fromJS({
name: 'Some widget2',
type: 'List',
defaultDataSource: 'daily',
dataSources: {}
}));
});
Qu'en est-il d'utiliser JSON.stringify
?
JSON.stringify(values) !== JSON.stringify(anothervalue);
Si vous savez qu'ils ne sont pas des objets circulaires et qu'ils ne contiennent pas de fonctions, je pense que c'est le moyen le plus rapide de les comparer.