简体   繁体   English

如何在循环内使用 React setState?

[英]How to use React setState inside a loop?

I have this createRoleMember function that updates a component's state so React can re-render table () inside the component and display the newly added roleMembers as rows.我有这个createRoleMember函数,它更新组件的状态,以便 React 可以在组件内重新渲染 table () 并将新添加的roleMembers显示为行。

  createRoleMember = (newRoleMember) => {
    this.setState((prevState) => {
      return { roleMembers: prevState.roleMembers.concat([newRoleMember]) };
    });
  };

The code works when I add a single member, but if the array contains more than one value, the createRoleMember function re-renders the table with the correct amount of new rows but with the same repeated username (always duplicating the last username in the array).当我添加单个成员时,代码有效,但如果数组包含多个值,则createRoleMember函数会使用正确数量的新行但使用相同的重复用户名重新呈现表(始终复制数组中的最后一个用户名)。

For example, if the array looks like this `["testOne, "testTwo", "testThree"], the table will be re-rendered like this:例如,如果数组看起来像这样`["testOne, "testTwo", "testThree"],表将像这样重新渲染:

testthree   xxx Aug 25, 2020    
testthree   xxx Aug 25, 2020    
testthree   xxx Aug 25, 2020

Instead of:代替:

testtone    xxx Aug 25, 2020    
testttwo    xxx Aug 25, 2020    
testthree   xxx Aug 25, 2020

If I reload the page, the table displays the correct data.如果我重新加载页面,表格会显示正确的数据。

How can I call createRoleMember (which contains setState ) inside a loop?如何在循环内调用createRoleMember (包含setState )?

More Context更多上下文

The createRoleMember function gets called in a loop that looks like this:在如下所示的循环中调用createRoleMember函数:

  aliasArray.forEach((currAlias) => {
    memberAttributes.alias = currAlias;
    const marshalledObj = AWS.DynamoDB.Converter.marshall(memberAttributes);

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

    axios
      .post(
        "https://xxxxxx.execute-api.us-west-2.amazonaws.com/xxx/xxx",
        params
      )
      .then(() => {
        createRoleMember(memberAttributes);
        const newRow = document.getElementById(
          `${memberAttributes.alias}-${memberAttributes.Role}`
        );
        newRow.classList.add("new-row");
      });
  });
  • aliasArray : an array of strings like "username1","username2". aliasArray :字符串数组,如“username1”、“username2”。

  • memberAttributes : an object with the member's data, eg, username, grantedBy, grantedOn. memberAttributes :一个包含成员数据的对象,例如用户名、grantedBy、grantedOn。

  • newRow : allows me to provide feedback to the user (highlights new row in green). newRow :允许我向用户提供反馈(以绿色突出显示新行)。

I believe the issue is in your code here:我相信问题出在您的代码中:

aliasArray.forEach((currAlias) => {
    memberAttributes.alias = currAlias; // Here's the problem

    // ...

    axios
      .post(/*...*/)
      .then(() => {
        createRoleMember(memberAttributes);
        // ...
      });
  });

Each time the forEach callback is invoked, you're updating the value of memberAttributes.alias .每次调用 forEach 回调时,都会更新memberAttributes.alias的值。 So after all the members of aliasArray have been iterated, the value of memberAttributes.alias is the last value of aliasArray .所有成员打完aliasArray已经迭代,价值memberAttributes.alias是最后一个值aliasArray

So when your requests come back and the success callback ( .then(...) ) is executed, memberAttributes.alias is going to be that last value of aliasArray for each invocation.因此,当您的请求返回并执行成功回调( .then(...) )时, memberAttributes.alias将成为每次调用的aliasArray最后一个值。 I believe your issue would be resolved by propagating currAlias through to the success callback like:我相信您的问题可以通过将currAlias传播到成功回调来解决,例如:

aliasArray.forEach((currAlias) => {
    memberAttributes.alias = currAlias;
    const marshalledObj = AWS.DynamoDB.Converter.marshall(memberAttributes);

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

    axios
      .post(
        "https://xxxxxx.execute-api.us-west-2.amazonaws.com/xxx/xxx",
        params
      )
      .then(() => {
        memberAttributes.alias = currAlias;
        createRoleMember(memberAttributes); 
        const newRow = document.getElementById(
          `${currAlias}-${memberAttributes.Role}` // Modified this line
        );
        newRow.classList.add("new-row");
      });
  });


createRoleMember = (newRoleMember) => {
    this.setState((prevState) => {
      return { roleMembers: prevState.roleMembers.concat([{...newRoleMember}]) };
    });
  };

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

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