我的应用程序使用带有react和typescript的redux。我正在处理应用程序不同位置使用的许多项目。我的状态如下:
{
items: {42: {}, 53: {}, ... }, //A large dictionary of items
itemPage1: {
items: [42, 34, 67, ...],
...
},
itemPage2: { ...
},
...
}
我想写一个高效的项目减少器,但项目很大,我不能每次都创建深度副本。显然,我不需要根据gaearon(从那里摘录):Redux并没有要求你在每个动作中深度克隆状态。它只是要求您为已更改的零件返回新对象。对于树中未更改的任何部分,都可以重用以前的状态。
这太棒了!然而,我对这一切都是新手,我不知道如何正确实施减速器。到目前为止,我的物品减速器里有这样的东西:
case UPDATE_ITEM_LABEL:
return (<any>Object).assign({}, state, {
item_id: (<any>Object).assign({}, state[action.item_id], {
label: action.value
})
})
因此,它将旧状态的所有元素复制到一个新对象中,然后将结果与具有新更新值的已更改对象合并。我希望第一次assign
期间的项目是通过引用传递的,因此不会被深度复制?如果是这种情况,那就好了,因为我可以深入复制一个项目,并为每个操作提供一些简单的参考。此外,我发现可以使用immutable.js来回答这个问题,如果我提出的方法有效,为什么人们会使用immutaable.js?
我做了一个快速测试,以确保我的方法能够完成任务:
var item1 = {prop1: 'item1', prop2: 'haha'};
var item2 = {prop1: 'item2', prop2: 'hehe'};
var items = {1:item1, 2:item2};
console.log(items);
此显示如预期:
[object Object] {
1: [object Object] {
prop1: "item1",
prop2: "haha"
},
2: [object Object] {
prop1: "item2",
prop2: "hehe"
}
}
现在我们使用assign
来获得下一个状态,修改项2的一个密钥:
var items = Object.assign({},items, { 2: Object.assign({}, items[2],
{
prop2: 'huhu'
})
});
console.log(items);
此显示如预期:
[object Object] {
1: [object Object] {
prop1: "item1",
prop2: "haha"
},
2: [object Object] {
prop1: "item2",
prop2: "huhu"
}
}
现在有趣的是,如果我们使用对item1和item2的初始引用来更改prop1
属性:
item1.prop1 = 'ITEM1'
item2.prop1 = 'ITEM2'
console.log(items);
我们发现只有item2被深度复制,这就是我想要的行为:
[object Object] {
1: [object Object] {
prop1: "ITEM1",
prop2: "haha"
},
2: [object Object] {
prop1: "item2",
prop2: "huhu"
}
}