我有2个不同的状态,一个状态包含第二个状态的一部分。事实是,当第二个状态更改时,第一个状态中的内容也更改了,我无法处理原因。
这是当我更改第二种状态时:
case 'UPDATE_IMAGES':
return Object.assign({}, state, {
runes: updateChosenState(state, action)
});
export function updateChosenState(state,action){
const img = state.images.slice();
let e = action.e;
imga[].id_ = action.id;
return img;
}
第一个状态是在操作中以这种方式访问,然后将其提供给reducer:
let img = getState().ImgReducer.images;
在化简器中,当它相关时,我需要执行一些功能:
const copy = images.slice();
items.image = copy[idGiven];
每当更改图像状态时,都会更改此行。即使是复制,它也改变了,我不明白为什么。我只想在第一个状态下拥有此东西的副本,对于这个状态,我不在乎图像是否在之后更改。
我觉得我正在直接访问ImgReducer状态,所以无论何时更改,我都有更新,但我不知道如何避免这种情况。
谢谢
答案 0 :(得分:1)
在数组上使用slice
时,返回的数组不是真正的克隆。相反,您得到了数组的shallow copy。因此,副本和数组内部的原始对象都指向相同的内存引用。
来自MDN上的Array#slice
文档:
要引用对象,请
slice
将引用复制到新数组中。原始数组和新数组都指向同一对象。如果引用的对象发生更改,则更改对于两个数组都是可见的。
您可以通过以下示例进行验证:
const original = { src: 'foo' }
const images = [original]
const copy = images.slice()
original.src = 'baz'
console.log(copy)
您需要对元素进行深层克隆。您可以使用传播操作符执行此操作:
const original = { src: 'foo' }
const images = [original]
const copy = images.slice().map(o => ({ ...o }))
original.src = 'baz'
console.log(copy)
达到相同目标的另一种方法是使用JSON#stringify
和JSON#parse
:
const original = { src: 'foo' }
const images = [original]
const copy = JSON.parse(JSON.stringify(original))
original.src = 'baz'
console.log(copy)