Вот в ореховой скорлупе вопрос:
let a = { foo: 'A'}
let c = { ... a } // shallow copy of a
a.foo = 'boo'
console.log(a)
console.log(c) // works as expected c.foo is NOT changed and still is 'A'
Как видно из приведенного выше примера со свойствами расширения и значения на основе, мелкое копирование работает, как и ожидалось.Однако, когда вы делаете это:
let x = { foo: { boo: 'A' }} // object as value this time
let y = { ... x } // shallow copy of x
x.foo.boo = 'beer'
console.log(x.foo.boo)
console.log(y.foo.boo) // should be 'boo' but it is 'beer'
Мелкая копия также не работает, так как clone
содержит ссылки, указывающие на старые x
объекты вместо клонированных.
Для исправленияэто, а также, чтобы сделать ваш код несколько более кратким, вы можете:
const state = { 1: {a: true, b: true, c: true}, 2: {a: true, b: true, c: true}, 3: {a: true, b: true, c: true}, }
const payload = { 2: {a: true, b: false, c: true} }
const merger = (...args) => _.mergeWith(...args, (a,b) => _.isArray(a) ? b : undefined)
console.log("Merged data:");
console.log(merger(_.cloneDeep(state), payload));
console.log("Manipulated state:");
console.log(state);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
Первый переключатель от lodash _.cloneDeep
, который позволит глубоко скопировать все дерево объектов, а также вы можете сделать свой метод merge
болеекраткий с ES6 spread
и т. д.