如何编辑状态数组中的项?

时间:2017-02-04 06:38:27

标签: reactjs

所以这是我的状态:

this.state = {
  ids: ['A', 'E', 'C']
};

我将如何修改状态以便' E'在索引1处更改为' B&#39 ;? 例如:

this.setState({
  ids[1]: 'B'
});

如何做到这一点?

6 个答案:

答案 0 :(得分:22)

我的建议是习惯使用不可变操作,因此不要修改内部状态对象。

正如react docs

所指出的那样
  

不要直接改变this.state,因为之后调用setState()可能   替换你所做的突变。 将此状态视为好处   不可变的。

在这种情况下,您可以 [1] 使用slice()来获取数组的新副本 [2] 操纵副本,然后使用新数组 [3] setState。这是一个很好的实践。

类似的东西:

const newIds = this.state.ids.slice() //copy the array
newIds[1] = 'B' //execute the manipulations
this.setState({ids: newIds}) //set the new state

答案 1 :(得分:13)

案例1:如果您知道索引,那么您可以这样写:

let ids = [...this.state.ids];     // create the copy of state array
ids[index] = 'k';                  //new value
this.setState({ ids });            //update the value

案例2 :如果您不知道索引,那么首先使用array.findIndex或任何其他循环来获取您要更新的项目的索引,在更新之后value并使用setState。

像这样:

let ids = [...this.state.ids];  
let index = ids.findIndex(el => /* condition */);
ids[index] = 'k';                  
this.setState({ ids });            

答案 2 :(得分:0)

基于@ mayank-shukla所写的内容(案例2:知道要替换的项目的索引),这也可以用Array.splice编写:

const replacement = 'B';
let copy = [...this.state.ids]
copy.splice(index, 1, replacement)

this.setState({ 
   ids: copy,
})

REPL Example

有两点需要注意:

  1. Array.splice 变异的;它将改变它操作的数组,但由于扩展运算符,这是数组的浅表副本。更多关于以下内容。
  2. 您无法直接指定拼接的结果,因为Array.splice的返回值实际上是已删除的元素。 又说明:不要将切片的结果分配给您要分配给setState中的ID的变量,否则最终只会删除已删除的值。
  3. 要跟进第1项中的浅层和深层副本,请注意,如果要替换对象引用(vs问题中的字符串文字),则需要使用lodash's cloneDeep之类的内容。

    虽然有handful of other ways around this

    您还可以在SO itself上阅读有关浅与深的更多信息。

答案 3 :(得分:0)

这是在setState中更改数组的特定索引的另一种解决方案:

this.setState({
  ...array,
  Object.assign([...array], { [id]: yourNewObjectOrValue })
})

答案 4 :(得分:0)

this.setState({
  ids: [ids[1]='B',...ids].slice(1)
});

上面的代码将创建两个值为 'B' 的数组项,
一个在开始,一个在指定位置。 只需使用切片运算符删除第一个数组元素。

另一种解决方案是直接使用拼接运算符来完成

this.setState({
  ids: [ids.splice(1,1,'B')]
})

答案 5 :(得分:0)

我意识到这个问题很老了,但今天有一个更好的答案。

immer 可用于支持使用熟悉的 API 以更明智的方式更改不可变对象。通过将函数传递给 this.setState,您可以使用它来转换您的状态。

this.setState(state => produce(state, state => {
  state.ids[1] = 'b'
}));

或者,如果您更喜欢柯里化,produce(fn) 是创建一个函数的有用快捷方式,该函数接受一个参数并将其转发到您的转换中:

this.setState(produce(state => {
  state.ids[1] = 'b'
}));

我发现当涉及深层状态更改时,Immer 很棒,但请注意,它不是免费的。