My problem is I can't keep the CurrentState when I update the post title, so when I throw an error to get the current state which is the state before I changed the post title I found that the current state also changed to the new state which is after I had changed the post title even I initialized it before the update!
I want just explanation for how it worked.
state = {
posts: [],
};
async componentDidMount() {
const { data: posts } = await axios.get(apiEndPoint);
this.setState({ posts });
}
handleUpdate = async (post) => {
let currentState;
currentState = this.state.posts;
console.log(currentState[0].title);
post.title = 'jsdhjs';
try {
await axios.put(apiEndPoint + '/' + post.id, post);
throw new Error('');
} catch (ex) {
alert('Something Failed While Updating The Post');
this.setState(currentState);
}
};
render(){
return(
<tbody>
{posts.map((post) => (
<tr key={post.id}>
<td>{post.title}</td>
<td>
<button
className='btn btn-info btn-sm'
onClick={() => this.handleUpdate(post)}
>
Update
</button>
</td>
</tr>
))}
</tbody>
)
}
You are mutating the title
of your old state.
currentState = this.state.posts;
This won't copy the posts of the current state, it will just store a reference to it in a local variable.
post.title = 'jsdhjs';
post
in this case is also just a reference to one of the original posts in the current state - by setting the title, you will set the title in currentState
as well, that's why "resetting" in the error case doesn't work.
To avoid this, make sure to not mutate anything within your state directly - only React should do that via setState
.
In your case, one way would be to shallow-copy the post object before changing the title, e.g. by using the spread operator:
const updatedPost = {
...post,
title: 'jsdhjs',
};
// ...
await axios.put(apiEndPoint + '/' + updatedPost.id, updatedPost);
// TODO in success case, call this.setState with updatedPost
Also, it seems like you are calling setState
with only the posts array while instead you should do setState({ posts: currentState })
to keep the original shape. But maybe that's just a simplification for the question.