[英]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.