javascript - react : Efficient updating of array state

标签 javascript reactjs

React 的基本思想之一是状态更改应该始终且仅通过 this.setState(...) 发生,而不是手动操作状态。但对于状态是深度数组(即对象文字数组(实际上是一些 JSON 数据))的情况,更新该状态变得非常昂贵。如果我只想更新这样一个数组的一个元素,代码将类似于以下内容。

handleChange(index, newElement){
    var newStateArray = _.cloneDeep(this.state.myArray);
    newStateArray[index] = newElement;
    this.setState({myArray: newStateArray });
}

我知道标准解决方案是使用浅复制,但这只是浅数组的复制。就我而言,事实并非如此,因此从 react 意义上来说,浅复制将是“错误的”,因为它会改变状态。那么实际上应该如何处理这个问题呢?我可以只使用浅拷贝,它可以工作,但感觉很脏并且在技术上是错误的。

编辑:或者澄清一下:如果我只使用浅拷贝并确保告诉 React 手动更新,是否会发生任何不好的事情?

编辑:噢,这似乎已经解决了。浅复制并不像我想象的那样起作用。我是 JS 新手,请原谅。供引用:

var a = [{a:1}, {b:2}, {c:3}]
var b = a.slice();
b[0] = 42; // I thought this would change a, but it doesn't!

最佳答案

只要您将所有对象视为不可变(即,如果您需要更改属性,请先进行浅复制),就不会出错。例如:

起始状态:

var A = {
    foo: 3,
    bar: 7
};
var B = {
    baz: 11,
    boop: 5
};
var C = {
    myA: A,
    myB: B
};

假设我们要更改 C->myB->boop。 A 中没有任何变化,因此我们不需要复制,但我们确实需要复制 B 和 C:

var newB = {
    baz: B.baz,
    boop: 1000000 // we have to update this in B, so we need a new B
};
var newC = {
    myA: C.myA,
    myB: newB    // we have to update this in C, so we need a new C
};

(显然,您会使用浅复制来制作每个部分的副本,然后将更改分配在顶部;为了清楚起见,我只是手动写出副本)

当我们提交 newC 作为新状态时,它将仅共享未更改的部分(在本例中为 A),这很好,因为它们始终被视为不可变对象(immutable对象)。

一般来说,当您更改任何属性时,您将需要制作保存该属性的对象的浅拷贝,以及该对象的父级及其父级的父级等,一直返回到根节点。您也可以以完全相同的方式考虑数组;为此,它们只是具有编号属性的对象。

如果您在进行更改的任何地方都遵循这些规则,您的浅数组副本将正常工作。这适用于任何有状态历史的情况,而不仅仅是reactjs。

关于javascript - react : Efficient updating of array state,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28010444/

相关文章:

jquery - 使用 CORS 响应 jQuery 请求时缺少 header

reactjs - 如何在部署在谷歌云上的 npx 命令创建的 React 应用程序中启用 https。需要使用从 Godaddy 购买的证书

javascript - 不同的 AES 实现不一致

javascript - 使用 firepad+firebase+ace 重放每个修订 ID 中读取对象的代码

javascript - 变量排序表的排序不正确

javascript - 如何从主 Controller 发出数据以 Angular 查看 Controller ?

javascript - 从即时创建的表单访问 ViewController 中的函数

javascript - 如何在 React 中使用 prop 双向绑定(bind) select 元素

reactjs - 改变 React 数组状态比克隆它更好/更快的方法?

ios - 用户登录后动态更改登录选项卡和我的个人资料选项卡