You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Context中DELETE_BLOG动作失效问题排查求助

MERN栈RetroBlog删除博客后无法实时更新UI问题排查与修复

问题描述

在基于MERN栈开发的RetroBlog项目中,点击删除按钮后,对应博客的<div>无法实时消失,仅页面刷新后才会移除。相关代码包含Blogs组件、Home组件及BlogContext的实现,怀疑React Context的DELETE_BLOG dispatch未正常工作。

问题核心原因

Home组件同时维护了本地blogs状态(useState)和Context中的状态,但UI渲染依赖的是本地useState的blogs,而非Context中的状态。当执行DELETE_BLOG时,Context中的状态已经更新,但Home组件的本地blogs未同步更新,导致UI无法实时刷新。

修复方案及代码修改

1. 调整Home组件:移除本地状态,直接依赖Context数据

删除Home组件中的useState声明,直接从Context获取博客列表,确保UI渲染与Context状态同步:

import { useEffect } from "react";
import Blogs from "../components/Blogs";
import { useBlogContext } from "../Hooks/useBlogContext";

const Home = () => {
    const { blogs, dispatch } = useBlogContext();

    useEffect(() => {
        const fetchBlog = async () => {
            const response = await fetch('/api/blog', {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            const json = await response.json();
            if (response.ok) {
                dispatch({ type: 'SET_BLOGS', payload: json });
            }
        };
        fetchBlog();
    }, [dispatch]);

    return (
        <div className="Home">
            <div className="Home-container">
                <h1>RetroBlog</h1>
                <p>Where you can create, update, and show ideas</p>
            </div>
            <h1>All Recent Blogs</h1>
            <Blogs blog={blogs} />
        </div>
    );
};

export default Home;

2. (可选优化)让Blogs组件直接读取Context数据

可以去掉Blogs组件的blog props,直接从Context获取数据,减少props传递层级:

import { Link, useNavigate } from "react-router-dom";
import { useBlogContext } from '../Hooks/useBlogContext';

const Blogs = () => {
    const navigate = useNavigate();
    const { blogs, dispatch } = useBlogContext();

    const handleClick = async (id) => {
        try {
            const response = await fetch(`/api/blog/${id}`, {
                method: 'DELETE',
            });

            const json = await response.json();
            if (response.ok) {
                // 若后端未返回完整博客对象,直接传递id即可
                dispatch({ type: 'DELETE_BLOG', payload: { _id: id } });
            } else {
                console.error('Failed to delete blog:', json);
            }
        } catch (error) {
            console.error('Error while deleting blog:', error);
        }
    };

    return (
        <div className="blogs-container">
            {blogs && blogs.map(blogItem => (
                <div key={blogItem._id} className="Home-blogs">
                    <div className="Blog-img-container">
                        <img src={blogItem.img_url} alt="Blog" className="Blog-img" />
                    </div>
                    <Link to={`/blogs/${blogItem._id}`}>
                        <h2 className="Blog-title">{blogItem.title}</h2>
                        <h3 className="Blog-author">{blogItem.author}</h3>
                        <p className="Blog-content">{blogItem.content}</p>
                        <p>{blogItem.createdAt}</p>
                    </Link>
                    <div className="blog-icons">
                        <span className="material-symbols-outlined" onClick={() => handleClick(blogItem._id)}>Delete</span>
                        <span className="material-symbols-outlined" onClick={() => navigate(`/blogs/update/${blogItem._id}`)}>Edit</span>
                    </div>
                </div>
            ))}
        </div>
    );
};

export default Blogs;

3. 后端接口校验

确保后端DELETE /api/blog/:id接口成功后,返回的数据包含被删除博客的_id(或直接传递请求的id作为payload),保证Context中filter逻辑能正确匹配并移除对应博客。

内容的提问来源于stack exchange,提问作者M. ARUN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:47:07