简体   繁体   English

反应 object 属性值被复制 on.push 循环内

[英]React object property value being duplicated on .push inside loop

I have a handleCreate function that takes care of taking some user data and inserting it into a database.我有一个handleCreate function 负责获取一些用户数据并将其插入数据库。

Inside the aliasArr.forEach() loop I POST into my DB new user instances for each element in the aliasArr array.aliasArr.forEach()循环中,我将POST数组中每个元素的新用户实例aliasArr到我的数据库中。 This particular code works as expected, if I check the DB, I will find the new members.此特定代码按预期工作,如果我检查数据库,我将找到新成员。

After saving the new members, I want to keep the members in the members array so I can pass it along to another function.保存新成员后,我想将成员保留在members数组中,以便将其传递给另一个 function。

For this, I'm doing members.push(memberAttributes);为此,我正在做members.push(memberAttributes); but if I log the contents of members I get the right amount of elements but the alias property value is duplicated (all other properties should have the same value cause they are being added into the same role in a batch operation).但是如果我记录members的内容,我会得到适量的元素,但是alias属性值是重复的(所有其他属性应该具有相同的值,因为它们在批处理操作中被添加到相同的角色中)。

If I have two new users, say: xyz and abc , I get:如果我有两个新用户,比如说: xyzabc ,我会得到:

[
    {alias: "abc", Role: "admin", "grantedBy": "someone"},
    {alias: "abc", Role: "admin", "grantedBy": "someone"},
]

Instead of:代替:

[
    {alias: "xyz", Role: "admin", "grantedBy": "someone"},
    {alias: "abc", Role: "admin", "grantedBy": "someone"},
]

Here's the code:这是代码:

 handleCreate = () => {
    const { memberAttributes } = this.state;
    const { role, createRoleMember } = this.props;
    const roleArr = [];
    roleArr.push(role);
    const aliasArr = memberAttributes.alias.split(",");
    let members = [];

    //false hardcoded during debugging.
    if (false /* await aliasIsAdmin(memberAttributes.alias, roleArr) */) { 
      this.setState({ userExists: true }); 
    } else {
      memberAttributes["Granted By"] = window.alias;
      memberAttributes.Role = role;
      memberAttributes.timestamp = Date.now().toString();
      this.handleClose();

      aliasArr.forEach((currAlias) => {
        memberAttributes.alias = currAlias;
        console.log("memberAttributes:", memberAttributes);

        members.push(memberAttributes);
        console.log("members", members);

        const marshalledObj = AWS.DynamoDB.Converter.marshall(memberAttributes);

        const params = {
          TableName: "xxx",
          Item: marshalledObj,
        };

        axios.post(
          "https://xxx.execute-api.us-west-2.amazonaws.com/xxx/xxx",
          params
        );
      });
    }
    createRoleMember(members); //passing members to this function to do more stuff.
  };

I'm wondering if this issue is due to memberAttributes being part of the component's state .我想知道这个问题是否是由于memberAttributes是组件的一部分state

The problem here is that you are pushing references to the same object into the array after changing a value within that object. So whenever you make the change to memberAttributes.alias , it's changing the alias to the most recent one.这里的问题是,在更改 object 中的值后,您将对同一 object 的引用推送到数组中。因此,无论何时对memberAttributes.alias进行更改,它都会将别名更改为最新的别名。 After that, all references to the same object (which in this case is every item in the members array) present the new value in alias.之后,对同一个 object(在本例中是members数组中的每一项)的所有引用都以别名呈现新值。

 const obj = { alias: 'abc', role: 'role1' } const arr = [] arr.push(obj) obj.alias = 'new alias' arr.push(obj) for (var mem of arr) { console.log(mem) }

To fix it, you need to create a new object each time and push it onto the array instead, like so:要修复它,您需要每次都创建一个新的 object 并将其推送到数组中,如下所示:

aliasArr.forEach((currAlias) => {
   // Creates a new object in memory with the same values, but overwrites alias
   const newMemberAttributes = Object.assign(memberAttributes, { alias: currAlias });
   console.log("memberAttributes:", newMemberAttributes);

   members.push(newMemberAttributes);
   console.log("members", members);
   ...
}

Similarly, you can use the spread operator to create a deep copy of the object and then reassign alias.同样,您可以使用扩展运算符创建 object 的深层副本,然后重新分配别名。

aliasArr.forEach((currAlias) => {
   // Creates a new object in memory with the same values, but overwrites alias
   const newMemberAttributes = { ...memberAttributes };
   newMemberAttributes.alias = currAlias
   console.log("memberAttributes:", newMemberAttributes);

   members.push(newMemberAttributes);
   console.log("members", members);
   ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM