ReactJs/Flux: 如何处理存储对象的编辑过程?

ReactJs/Flux: How to handle editing process of store objects?

处理从商店检索到的编辑对象的最佳方式是什么?

例如假设您有一个 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 从商店中 return 克隆一个以确保原始对象保持不变。但这将为每个 get 请求 return 个新对象,这似乎根本没有性能。

每次实际开始影响性能时,您必须执行 很多 次请求才能创建克隆。

复制对象并不是特别昂贵的操作,当您的引用超出范围时垃圾收集器会进行清理,因此您可能也不需要担心内存问题。

与知道商店中的数据不能从应用程序的其他地方随机变化所带来的可预测性的好处相比,这些都是非常小的权衡。

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 可以像对象一样使用,但是当您尝试更改或创建 属性 时它不会改变它,它 returns 一个 new 不可变映射。

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 中很好地介绍了这些概念。值得一看。