Reputation: 11
So I just spent an hour debugging this code and finally got it to work, but I would want to know why this happened in the first place. I have a function that takes a value from my state, operates on it and saves the output in another variable in the state. This is the fuction:
getFolderNames = async () => {
const promises = this.state.rows.map(async item => {
if (item[".tag"] == "folder" && item.name.length > 20) {
item.name = await getFolderName(item.name);
return item;
} else return item;
});
const result = await Promise.all(promises);
this.setState({
rowsToDisplay: result
});
};
when i run this function, it was updating both the rows and rowsToDisplay to the result variable when i was only calling setState on only one of them.
Changing the function as below solves the issue but I would like to know why.
getFolderNames = async () => {
const promises = this.state.rows.map(async item => {
if (item[".tag"] == "folder" && item.name.length > 20) {
let item2 = {
...item
};
item2.name = await getFolderName(item.name);
return item2;
} else return item;
});
const result = await Promise.all(promises);
this.setState({
rowsToDisplay: result
});
};
Upvotes: 1
Views: 62
Reputation: 580
It's because of how JavaScript handles variables. When you set a variable to an array or object, it doesn't make a new object but rather just references the original array/object.
As such, if you set a variable to equal some object, and then set a property of that variable, the original object will also be updated. Check this snippet for an example.
var foo = {changed: false};
var bar = foo;
bar.changed = true;
console.log("foo", foo.changed)
console.log("bar", bar.changed)
You can read more about the subject here: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
I hope this helps you in the future, since I know I also spent many hours banging my head against exactly the sort of cases you described in your original question.
Upvotes: 1