首页 > 解决方案 > 即使指定了索引,对象中的所有数组值也会在 this.setState 中更新

问题描述

我有一个动态选项表。选择表单类型时,它将基于数组索引更新特定的数组类型。例如:this.state.menuInput = [{"title" : "array 1" , "type" : ""} , {"title" : "array 2" , "type" : ""}]。当我更改数组 2 值的表单类型时,类型应该更新为所选的任何内容。

它应该是这种格式[{"title" : "array 1" , "type" : ""} , {"title" : "array 2" , "type" : "radio_button"}]。目前,当我改变状态时,两个数组中的“类型”都在更新。

像这样: [{"title" : "array 1" , "type" : "radio_button"} , {"title" : "array 2" , "type" : "radio_button"}]。即使我专门将数组索引硬编码在setstate.

我怎样才能根据索引改变数组值?

 menuTypeOption(index, menuType){

    this.setState(prevState => {
        const newMenu = [...prevState.menuInput];
        newMenu[index]['title'] = menuType;
        return {menuInput: newMenu};
    } , function(){
        console.log(this.state.menuInput);
    })

}

标签: javascriptreactjs

解决方案


在这一行const newMenu = [...prevState.menuInput];中,您不会制作数组的深层副本,而只会制作指向相同对象的新数组。

所以newMenu[index]['title'] = menuType;改变原始对象。

您可以创建具有更改属性的新对象,而不是变异:

newMenu[index] = {...newMenu[index], title: menuType};

如果原始数组中已经有两个指向同一个对象的指针,那么这个解决方案也可以工作,因为它会创建新对象,并且不会改变共享对象。

可以这样证明:

const obj = {foo: 'bar'};
let arr = [obj, obj]; // same object used twice
// now if we do `obj.foo = 'new value';`, it'll change both values in array
arr = [...arr];
arr[1] = {...arr[1], foo: 'new value'};
// now we have two different objects in arr: one points to old, and one points to new copy with changed values

推荐阅读