在React中处理对象的状态和数组

时间:2014-12-20 03:10:18

标签: javascript arrays reactjs

我们都知道React文档说不要直接改变this.state。我想我对状态数组和不变性有一个挥之不去的问题:

如果我有一个处于状态的对象数组,那么在以任何方式改变该数组时,我是否总是使用immutability helper中的this question

或者使用[].concat()[].slice()作为已解答的herehere是完全可以接受的吗?

我再次问这个问题是因为[].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()来改变状态存储的对象数组?

1 个答案:

答案 0 :(得分:2)

您主要需要考虑边界。如果您只在拥有它的组件中使用此数组,并可选择将其作为props传递:它并不重要。您可以以任何方式对其进行修改,除非其他组件存在严重问题,否则他们永远不会知道差异,因为当组件更新其状态时,它们会获得新的道具。

如果你将这个数组传递给某种api,比如一个助手动作创建者或作为道具传递给你的函数,那么你可能会遇到一些非常严重且难以追踪的错误。这就是不变性很重要的地方。

例如,在这种情况下,您可能想要检查回调中某人的某些属性,但是如果people[0].name可能已更改,则您有竞争条件。

function savePeople(people){
  $.post('/people/update', people, function(resp){
    if (people[0].name === ...) {
      // ...
    }
  });
}