我一直在阅读有关redux的内容。对我来说有一件奇怪的事情。在人们给出的大多数示例中,所有复制逻辑都通过reducer处理。 我正在使用打字稿,并希望采用更基于类的方法。但也许我错过了一些东西。
假设我有一个购物车类。随着推车减速机和推车动作。 它看起来如下:
export class Cart
{
private items:{[key:string]:number} = {};
constructor(items:{[key:string]:number} = {})
{
Object.assign(this.items, items);
}
public addItem(id:string)
{
this.items[id] = this.items[id]?this.items[id]+1:1;
}
public removeItem(id:string)
{
this.items[id]--;
if(this.items[id] <= 0)
{
delete this.items[id];
}
}
public setItemsCount(id:string, count:number)
{
this.items[id] = count;
}
public clone():Cart
{
return new Cart(Object.assign({}, this.items));
}
}
所以,我在这里将克隆逻辑包含在一个类中。
在我的减速机中,我会选择签名:
function reducer(state = new Cart(), action:Action): Cart {
//first clone, then mutate, then return
}
或者,实际上,如何通过通用方法简单地深度克隆对象,然后改变它们然后返回?这种方法有什么不好的?
答案 0 :(得分:4)
由于多种原因,这被认为是不好的做法。
首先,不鼓励将类实例保持在状态because it will break time-travel debugging。你可以这样做,但这不是“正确”的方式。
其次,你的班级正在直接改变其内容。这也将打破时间旅行调试,result in your connected React components not re-rendering properly。
第三,Redux鼓励采用更具功能性的方法,而不是OOP。
您可能需要阅读我最近的两篇博客文章The Tao of Redux, Part 1 - Implementation and Intent和The Tao of Redux, Part 2 - Practice and Philosophy,其中详细介绍了Redux需要哪些技术限制以及为什么,为什么使用Redux存在常见做法,以及为什么其他方法可能可能但不被认为是惯用的。
答案 1 :(得分:1)
你可能会这样。毕竟......您将尊重Redux架构所需的不变性合同。
但我不建议你这样做。
深度克隆根本不具备高效性。您的商店越大,您的应用就越慢。
另外,为了感到荣幸我用class
尝试了这种方法:
https://github.com/maxime1992/pizza-sync/blob/5212a29ee9be916383f759a3a129f7b580ed32ea/frontend/src/app/shared/state/orders/orders.reducer.ts
并没有那么糟糕。但我最终使用了一个简单的功能。
有一件事,你的actions
在这里打不开,这样你就会失去打字稿的一些好处。
而不是这样做,您应该为每个操作创建class
,如本演讲中所述https://www.youtube.com/watch?v=cyaAhXHhxgk
另外,我已经制作了一个可以帮助您入门的ngrx启动器:https://github.com/maxime1992/angular-ngrx-starter