使用传播运算符更新数组对象的对象值

时间:2019-05-13 07:58:15

标签: javascript reactjs

我正在尝试从数组对象和对象更新值。我的示例代码如下。没有得到预期的结果。有人可以帮忙会很好吗?

    let array = [
        {   
            id:"01",
            "name": {
                "value": "jaison",
                "error": null
            },
            "email": {
                "value": "jaison@yopmail.com",
                "error": null
            }
        },
        {
            id:"02",
            "name": {
                "value": "jaison 1",
                "error": null
            },
            "email": {
                "value": "jaison1@yopmail.com",
                "error": null
            }
        }
    ];

    this.state{
        data:array
    }

    //This two data getting a from a form
    const key = "02";
    const editedData = {name:"updated jaison 1", email:"updatedjaison1@yopmail.com"}

    const newData = [...this.state.data];

    const index = newData.findIndex(item => key === item.id);

    let item = newData[index];

    //Working as expcted 
    console.log('1', item);

    Object.keys(editedData).forEach(function (key) {
      item[key] = editedData[key];
    });

    //Working as expcted 
    console.log('2', item);

    this.setState({ data: [...this.state.data, item]}, () => {
        //Not Working as expcted 
        console.log(this.state.data);
    });

    Expected result
   let array = [
    {   
        id:"01",
        "name": {
            "value": "jaison",
            "error": null
        },
        "email": {
            "value": "jaison@yopmail.com",
            "error": null
        }
    },
    {
        id:"02",
        "name": {
            "value": "updated jaison 1",
            "error": null
        },
        "email": {
            "value": "updatedjaison1@yopmail.com",
            "error": null
        }
    }
];

3 个答案:

答案 0 :(得分:2)

item[key]内部更新forEach时,它只是使用字符串值更新nameemail。而且,它会突变state

相反,您可以循环遍历editedData对象来更新该特定索引的克隆。使用spread syntax保持error和其他属性不变,并仅更新value属性。然后更新克隆的data数组的索引,并像这样调用setState

const key = "02",
      editedData = { name: "updated jaison 2", email: "updatedjaison2@yopmail.com" },
      data = [...this.state.data],
      index = data.findIndex(item => key === item.id),
      updatedData = { ...data[index] };

// loop through and update only the keys you need 
for(const key in editedData) {
  updatedData[key] = { ...updatedData[key], value: editedData[key] }
}

data[index] = updatedData;

this.setState({ data })

答案 1 :(得分:1)

我会执行以下操作,而不是查找索引并使用forEach遍历数组:

const updatedArray = newData.map(item => {
   // if editedData has a key attribute:
   if (item.id === editedData.key) {
       return editedData; //you'd need to add a key attribute to the data
   } else {
       return item;
   }
});
this.setState({data: updatedArray});

答案 2 :(得分:0)

您可以只使用map

   let array = [
        {   
            id:"01",
            "name": {
                "value": "jaison",
                "error": null
            },
            "email": {
                "value": "jaison@yopmail.com",
                "error": null
            }
        },
        {
            id:"02",
            "name": {
                "value": "jaison 1",
                "error": null
            },
            "email": {
                "value": "jaison1@yopmail.com",
                "error": null
            }
        }
    ];

    const key = "02";

    const updated = array.map(item => {
        if (item.id === key) {
            return {id: key, name:"updated jaison 1", email:"updatedjaison1@yopmail.com"}
        }
        return item;
    });

setState({data: updated});