我们都知道React文档说不要直接改变this.state
。我想我对状态数组和不变性有一个挥之不去的问题:
如果我有一个处于状态的对象数组,那么在以任何方式改变该数组时,我是否总是使用immutability helper中的this question?
或者使用[].concat()
或[].slice()
作为已解答的here和here是完全可以接受的吗?
我再次问这个问题是因为[].concat()
和[].slice()
确实返回了新的数组,但只返回浅拷贝数组。如果我改变数组的一个元素,它也会改变状态中的数组,违反了Reactjs State的第一条规则(我一直在看太多的FMA:兄弟会):
var arr1 = [{ name : "bill" }, { name : "chet" }];
var arr2 = arr1.slice();
// this changes both arrays
arr2[0].name = "kevin";
// check
(arr1[0].name === arr2[0].name) // => true; both are "kevin"
(arr1[0] === arr2[0]) // => true; only shallow copy
// this changes arr2 only
arr2.push({ name : "alex" });
// check again
(arr1.length === arr2.length) // => false;
(arr1[0].name === arr2[0].name) // => still true;
(arr1[0] === arr2[0]) // => still true;
我了解插件update
最常用于覆盖shouldComponentUpdate
,但对于我正在做的事情,我不需要覆盖该功能;我只需要通过向数组添加新元素(使用concat或slice解决)或通过更改现有元素的属性(通过使用React.addons.update解决)来变异状态中保存的数组中的对象。
TL; DR
如果没有覆盖shouldComponentUpdate
,我应该何时使用React.addons.update
而不是[].slice()
或[].concat()
来改变状态存储的对象数组?
答案 0 :(得分:2)
您主要需要考虑边界。如果您只在拥有它的组件中使用此数组,并可选择将其作为props传递:它并不重要。您可以以任何方式对其进行修改,除非其他组件存在严重问题,否则他们永远不会知道差异,因为当组件更新其状态时,它们会获得新的道具。
如果你将这个数组传递给某种api,比如一个助手动作创建者或作为道具传递给你的函数,那么你可能会遇到一些非常严重且难以追踪的错误。这就是不变性很重要的地方。
例如,在这种情况下,您可能想要检查回调中某人的某些属性,但是如果people[0].name
可能已更改,则您有竞争条件。
function savePeople(people){
$.post('/people/update', people, function(resp){
if (people[0].name === ...) {
// ...
}
});
}