处理从商店检索的编辑对象的最佳方法是什么?
E.g。假设你有一个ProductStore 你有一个EditProductComponent。如果您设置正在编辑的州产品,如下所示:
this.state.product = ProductStore.getProductById(1);
问题是当用户在进行一些更改后取消编辑时,它们会在商店对象上保留,因为它直接分配给状态。例如。用户修改产品名称:
this.state.product.name = value; //new value is assigned to the store object as well
我如何才能使其具有高效性并使之成为商店产品保持只读?
我正在考虑使用Object.assign从商店返回克隆,以确保原始对象保持不变。但是这会为每个获取请求返回新对象,这看起来根本不具备性能。
答案 0 :(得分:0)
在每次实际开始影响性能时创建克隆之前,您必须执行很多请求。
复制对象并不是特别昂贵的操作,当引用超出范围时,垃圾收集器会清理,因此您可能不必担心内存。
与可预测性的好处相比,这些是非常小的权衡,因为您知道商店中的数据无法从应用程序的其他位置随机变异。
getProductById: function(id) {
var product = this.products[id];
return Object.assign({}, product);
}
但是,你可以进一步改进,让它们变成不可变的。
getProductById: function(id) {
var product = this.products[id];
return Object.freeze(product);
}
现在不再可能改变产品了。如果应用程序的另一部分想要编辑它,则必须创建一个应用了适当更改的新副本。
// the immutable product that came from the store
const product = { ... };
// with ES6
const editedProduct = Object.assign({ editedProp: newValue }, product);
// or with ES7
const editedProduct = { editedProp: newValue, ...product };
每当您想要修改对象时,您还必须记住更新商店。
ProductStore.edit(editedProduct.id, editedProduct);
这使您可以在整个应用程序中强制实施可预测性。
另一种方法是使用实现不可变数据结构的库,例如Immutable.js。
它带有immutable map type,可以像对象一样使用,但是当您尝试更改或创建属性时,它不会改变它,而是返回 new 不可变映射。 / p>
var product = Immutable.Map({ name: 'product_name' });
var editedProduct = product.set('name', 'new_name');
// now tell the store that you've edited it
// ...
这里的好处是Immutable.js使用一种称为结构共享的技术来确保在内部尽可能多的对象在两个版本之间共享,使它们几乎与常规可变数据结构一样有效。
这些概念在图书馆的创建者的a great video中得到了很好的体现。值得一看。