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 = (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).
For example, if the array looks like this `["testOne, "testTwo", "testThree"], the table will be re-rendered like this:
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?
More Context
The createRoleMember
function gets called in a loop that looks like this:
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".
memberAttributes
: an object with the member's data, eg, username, grantedBy, grantedOn.
newRow
: allows me to provide feedback to the user (highlights new row in green).
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
. So after all the members of aliasArray
have been iterated, the value of memberAttributes.alias
is the last value of 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. I believe your issue would be resolved by propagating currAlias
through to the success callback like:
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}]) };
});
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.