Re-render List after deleting item in child component
You can pass a reference to a function from the parent component AdminBlogListView
into the child component BlogListItem
, such that it is invoked when a blog post is deleted. That function will have the effect of either repopulating the blog posts or manually removing it from the data (that implementation bit is up to you).
Solution 1: Repopulate all blog posts on deletion
This is a quick fix with a bit of code smell (because you're essentially querying the server twice: once to delete the post and another to fetch posts again). However it is an escape-hatch type of situation and is simple to implement.
When you are rendering BlogListItem
, we can pass a function, say onDelete
, which will invoke getBlogPosts()
to manually repopulate the blog posts from your server:
<BlogListItem key={post._id} post={post} onDelete={getBlogPosts} />
Then it is a matter of ensuring BlogListItem
invokes onDelete()
when deleting a blog post:
const handleDelete = async (event) => {
event.preventDefault();
const choice = window.confirm("Are you sure you want to delete this post?");
if (!choice) return;
await deleteBlogPost(post._id);
// Invoke the passed in `onDelete` function in component props
props.onDelete();
};
Solution 2: Delete a specific blog post by ID in the parent
Similar to the solution above, but ensure that you are passing a function from the parent that can delete a post by a specific ID (from the argument). This saves you an additional trip to the server.
In your component AdminBlogListView
, define a function that can mutate the blogposts
state by removing a blog post by ID. This can be done by leveraging functional updates:
const onDelete = (id) => {
setBlogposts((currentBlogPosts) => {
const foundBlogPostIndex = currentBlogPosts.findIndex(entry => entry._id === id);
// If we find the blog post with matching ID, remove it
if (foundBlogPostIndex !== -1) currentBlogPosts.splice(foundBlogPostIndex, 1);
return currentBlogPosts;
})
}
NOTE: The code above assumes that the blog post ID is stored in the _id
key. I have simply inferred that from your code, since you have not shared the shape of the data.
Then in your BlogListItem
component, it's the same logic as solution #1, but you need to pass the ID into it when invoking it:
const handleDelete = async (event) => {
event.preventDefault();
const choice = window.confirm("Are you sure you want to delete this post?");
if (!choice) return;
await deleteBlogPost(post._id);
// Invoke the passed in `onDelete` function in component props with post ID as an argument
props.onDelete(post._id);
};