Reputation: 3423
I have a simple React app with a table of posts:
In the beginning, the app always has 100 posts.
Here's how I handle DELETE operation:
handleDelete = async post => {
const oldPosts = this.state.posts;
const posts = this.state.posts.filter(n => n.id !== post.id);
this.setState({ posts });
try {
await axios.delete(`${apiEndpoint}/${post.id}`);
console.log(oldPosts);
} catch (e) {
alert("There was an error while removing post " + post.id);
}
};
oldPosts variable contains a REFERENCE to posts array of state. As you can see in the next two lines, I'm updating state with a smaller amount of posts (99 of them). I would expect my oldPosts reference to point to this 99-element array. However, when it's console.logged, I see 100 elements. Why is that?
Upvotes: 1
Views: 59
Reputation: 138327
const oldPosts = this.state.posts;
That copies the reference to the array into the oldPost
variable. If the array inside this.state.posts
get changed, you will see those changes inside oldPosts
, but if the reference itself gets changed, then oldPost
and this.state.posts
point to two different arrays.
Using .filter
you do create a new array.
Upvotes: 2
Reputation: 104399
I would expect my oldPosts reference to point to this 99-element array. However, when it's console.logged, I see 100 elements. Why is that?
Nice question, let me try to explain. See the case is, array will be stored in some memory location and this.state.posts
will have the ref to that array
. You are referencing the same array
by oldPosts
, it means oldPosts
is pointing to array not to this.state.posts
.
When we update the value of this.state.posts
, it will have a new ref, ref to newly created array
, not to old array. But that oldPosts
will still point to old array.
Even if you assign any value other than an array, it will never effect the value of oldPosts
.
Check this example, you will get a better idea:
// consider this as state obj
let obj = {
posts: [1, 2, 3, 4],
}
let oldPosts = obj.posts;
let newPosts = obj.posts.filter(el => el < 4);
// same as setState
obj.posts = newPosts;
// still point to old array
console.log('oldPosts', oldPosts);
// it will have the new array
console.log('obj.posts', obj.posts);
obj.posts = 10;
// now it will have a totally new value
console.log('obj.posts', obj.posts);
Check this another example:
let a = [1, 2, 3, 4];
let b = a;
/*
a and b both points to same array, but if we assign a
new value to a, b will still points to array
*/
a = 10;
// by changing the value of a, it will not affect b
console.log('a', a);
// still point to array
console.log('b', b);
Upvotes: 1
Reputation: 469
You are not updating your oldPosts state. this should work
this.setState({ oldPosts : posts });
Thanks
Upvotes: 0
Reputation: 22885
You are assigning 100 posts
to oldPosts
. Then you are filtering posts
to get a new array and saving in state. Filter returns a new array and does not updates the actual array i.e. oldPosts
. If you want this behavior, you can use Array.prototype.splice
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
Upvotes: 0