I have a react application and I need help getting a component to rerender.
The component represents a blog. It lists out all the blogs it pulls from the database. There's a form at the bottom for adding new posts. When I add a new post, I not only send it the backend to be saved to the database, but I add it to the list of blogs on the front end so that it shows up right away in the UI. <-- This is the problem. The post is being added to the frontend array, which is in the state, but it doesn't show up in the UI unless I refresh the page.
Here's my code:
submitHandler(event) {
event.preventDefault();
let formData = new FormData();
formData.append('title', this.postTitleRef.current.value);
formData.append('body', this.postBodyRef.current.value);
if (this.state.file) {
formData.append('image', this.state.file);
}
if (this.state.editPostId) {
formData.append('postId', this.state.editPostId);
const editPost = this.state.blogPosts.find(p => p.id === this.state.editPostId);
if (editPost.filename) {
formData.append('filename', editPost.filename);
}
axios.patch('/blogs', formData, {
headers: {
Authorization: this.state.accessToken,
'content-type': 'multipart/form-data'
}
}).then(response => {
const existingPost = this.state.blogPosts.find(p => p.id === this.state.editPostId);
existingPost.title = this.postTitleRef.current.value;
existingPost.body = this.postBodyRef.current.value;
existingPost.updatedAt = response.data.updatedAt;
existingPost.filename = response.data.filename || existingPost.filename;
existingPost.imageUrl = response.data.imageUrl || existingPost.imageUrl;
this.state.blogPosts.sort((p1, p2) => p1.updatedAt > p2.updatedAt ? -1 : 1);
this.clearForm();
}).catch(err => {
console.log('err=', err);
});
} else {
axios.post('/blogs', formData, {
headers: {
Authorization: this.state.accessToken,
'content-type': 'multipart/form-data'
}
}).then(response => {
this.state.blogPosts.unshift({
id: response.data.id,
createdAt: response.data.createdAt,
updatedAt: response.data.createdAt,
filename: response.data.filename || null,
title: this.postTitleRef.current.value,
body: this.postBodyRef.current.value,
imageUrl: response.data.imageUrl || null
});
this.clearForm();
}).catch(err => {
console.log('err=', err);
});
}
}
When I put console logs in to see the contents of this.state.blogPosts, it shows that the new post is indeed added. But the new post doesn't show up on the screen unless I refresh the page.
Does it have anything to do with the fact that I'm calling event.preventDefault()?
Does it have anything to do with the fact that I'm adding the new post to an array in the state (this.state.blogPosts) rather than calling setState(...)?
Not even this.forceUpdate() seems to work.
Can anyone see what I'm doing wrong? Thanks.