将值添加到状态数组的最佳方法是什么

IT技术 memory state reactjs
2021-03-26 05:58:30

我有一个状态数组,比如说 this.state.arr。我想向这个 state 属性添加一些东西,然后再更改一些属性。

选项1

onChange(event){
    this.state.arr.push('newvalue');
    ...
    this.setState({some:'val',arr:this.state.arr})
}

选项 2

onChange(event){
    var newArr = this.state.arr;
    ...
    newArr.push('newvalue');
    ...
    this.setState({some:'val',arr:newArr})
}

所以..我知道 this.state 应该被视为不可变的。但是可以像在选项 1 中那样使用它,我仍然从中设置状态,或者我是否需要使用选项 2 之类的东西,因此总是首先在内存中制作一个副本

6个回答

目前,这是最好的方法。

this.setState(previousState => ({
    myArray: [...previousState.myArray, 'new value']
}));
@PubuduJayasankasetFoo(prevState => [...prevState.slice(0, pos), newItem, ...prevState.slice(pos)])带有钩子,但您可以在类组件中的特定键上使用类似的传播模式。
2021-05-27 05:58:30
如果我希望“新值”成为我传入的参数。我是否只是这样做 onChange = (id) => { this.setState(prevState => ({ tags: [...prevState.tags, id] })); }
2021-05-29 05:58:30
这对我有用。它也适用于添加到数组中:this.setState((prevState) => ({ myArray: [values, ...prevState.myArray], }));
2021-06-06 05:58:30
如何将新值添加到数组中的特定位置?
2021-06-09 05:58:30

您提供的两个选项是相同的。它们都将仍然指向内存中的同一个对象并具有相同的数组值。您应该像您所说的那样将状态对象视为不可变的,但是您需要重新创建数组,使其指向一个新对象,设置新项目,然后重置状态。例子:

onChange(event){
    var newArray = this.state.arr.slice();    
    newArray.push("new value");   
    this.setState({arr:newArray})
}
Slice 将创建一个新的数组浅拷贝,使其不可变。
2021-05-24 05:58:30
@Butters FWIW,这并不能使它不可变对象,因为该数组仍可突变。这里是字符串,所以这不是问题,但在一般情况下,slice仍然允许原位更新,绕过正常状态检查。
2021-06-08 05:58:30

使用 concat 的另一种简单方法:

this.setState({
  arr: this.state.arr.concat('new value')
})
将此更改为已接受的答案,因为它不仅是最后一个冗长的,而且还是根据 jsperf 最快的解决方案
2021-06-11 05:58:30
我发现这是最具表现力和最不冗长的方法。
2021-06-20 05:58:30
如果未按预期顺序调用 setState,这可能会导致状态不同步。最好使用 setState(prevState, ...)。
2021-06-21 05:58:30

如果您使用 ES6 语法,您可以使用扩展运算符将新项目作为单行添加到现有数组中。

// Append an array
const newArr = [1,2,3,4]
this.setState(prevState => ({
  arr: [...prevState.arr, ...newArr]
}));

// Append a single item
this.setState(prevState => ({
  arr: [...prevState.arr, 'new item']
}));

现在最好的离开。

this.setState({ myArr: [...this.state.myArr, new_value] })
我想知道如何将新值插入数组的中间而不是将其添加到末尾?
2021-05-29 05:58:30