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

Reactjs 如何编辑状态数组中的项?,reactjs,Reactjs,这就是我的状态: this.state = { ids: ['A', 'E', 'C'] }; 如何修改状态,使索引1处的“E”更改为“B”? 例如: this.setState({ ids[1]: 'B' }); 如何做到这一点?案例1:如果你知道索引,那么你可以这样写: let ids = [...this.state.ids]; // create the copy of state array ids[index] = 'k'; //

这就是我的状态:

this.state = {
  ids: ['A', 'E', 'C']
};
如何修改状态,使索引1处的“E”更改为“B”? 例如:

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

如何做到这一点?

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

let ids = [...this.state.ids];     // create the copy of state array
ids[index] = 'k';                  //new value
this.setState({ ids });            //update the value
案例2:如果您不知道索引,则首先使用或任何其他循环获取要更新的项的索引,然后更新值并使用setState

像这样:

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

我的建议是习惯使用不可变操作,这样就不会修改内部状态对象

正如报告中所指出的:

永远不要直接改变this.state,因为之后调用setState()可能会 替换你所做的变异将此.state视为 不可变。

在这种情况下,您可以使用[1]获取阵列的新副本,[2]操作副本,然后,[3]设置新阵列的状态。这是一个很好的做法

诸如此类:

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

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

这里有两点需要注意:

  • 数组。拼接
    是变异的;它将更改正在操作的阵列,但由于“扩展”操作符,这是阵列的浅拷贝。下面将详细介绍
  • 不能直接指定拼接结果,因为
    数组的返回值。拼接
    实际上是已删除的元素AKA:不要在
    setState
    中将切片的结果分配给要分配给ID的变量,否则最终只会得到已删除的值。
  • 要继续使用第1项中的浅拷贝和深拷贝,请注意,如果要替换对象引用(问题中的vs字符串文本),则需要使用以下内容

    不过,还有一个问题


    您还可以阅读有关浅层与深层的更多信息。

    下面是另一个在设置状态中更改特定数组索引的解决方案:

    this.setState({
      ...array,
      Object.assign([...array], { [id]: yourNewObjectOrValue })
    })
    
    上述代码将创建两个值为“B”的数组项,
    一个在起始位置,一个在指定位置。 只需使用slice操作符删除第一个数组元素

    另一种解决方案是使用splice操作符直接执行此操作

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

    我意识到这个问题由来已久,但今天有了更好的答案

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

    this.setState(state=>product(state,state=>{
    state.ids[1]=“b”
    }));
    
    或者,如果您更习惯使用curry,
    product(fn)
    是创建函数的一个有用的快捷方式,该函数接受参数并将其转发到转换中:

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

    我逐渐发现,当涉及到深度状态更改时,Immer非常棒,但请注意,它并不是免费的。

    我认为这句话的意思是:
    this.state.a='a'
    ,不要直接更改任何状态变量值。将this.state视为不可变,始终使用
    setState
    更改状态值。如果我错了,请纠正我??数组是JS中的对象,因此它们通过“引用”传递(如果使用新字符串设置状态键,则没有问题)。但是从
    this.state修改相同的数组/对象将更改相同的内部对象。谢谢。我花了太多时间想知道为什么React没有看到状态改变,而只是用修改过的数组副本更新状态。直到我使用
    slice()
    制作了那个副本,它才看到状态发生了变化。我花了一个小时的时间搜索,找到了一个直截了当的简单解释,说明了如何做到这一点。复制阵列并编辑副本,然后从副本中设置状态。简单。谢谢你!“您不能直接分配拼接的结果,因为Array.splice的返回值实际上是已删除的元素。AKA:不要将切片的结果分配给您打算在setState中分配给ID的变量,否则您将只得到已删除的值。”“您的示例不就是这样做的吗?@Aaron在文章中说,是的。在REPL中,没有。我将更新帖子本身。今天Array.prototype.map()是您最好的朋友,请看
    this.setState({
      ids: [ids.splice(1,1,'B')]
    })
    
    this.setState(produce(state => {
      state.ids[1] = 'b'
    }));