Search code examples
reactjsreact-hooksreact-context

this react context "DELETE_BLOG' is not Working properly is there any problem in the code?


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

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

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

            const json = await response.json();
            if (response.ok) {
                dispatch({ type: 'DELETE_BLOG', payload: json });
            } else {
                console.error('Failed to delete blog:', json);
            }
        } catch (error) {
            console.error('Error while deleting blog:', error);
        }
    };

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

export default Blogs;

the blog prop comes from:

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

const Home = () => {
    const [blogs, setBlogs] = useState(null);
    const { 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) {
                setBlogs(json);
                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;

this is my delete blog code and there is dispatch which is not not woking properly

import { createContext, useReducer } from 'react';

// Create BlogContext
export const BlogContext = createContext();

// BlogReducer to handle actions
export const BlogsReducer = (state, action) => {
    switch (action.type) {
        case 'SET_BLOGS':
            return {
                blogs: action.payload
            };
        case 'CREATE_BLOG':
            return {
                blogs: [action.payload, ...state.blogs]
            };
        case 'DELETE_BLOG':
            return {
                blogs: state.blogs.filter((b) => b._id !== action.payload._id)
            };
        case 'UPDATE_BLOG':
            return {
                blogs: state.blogs.map((b) =>
                    b._id === action.payload._id ? action.payload : b
                )
            };
        default:
            return state;
    }
};


// BlogContextProvider component
export const BlogContextProvider = ({ children }) => {
    const [state, dispatch] = useReducer(BlogsReducer, {
        blogs: null
    });

    return (
        <BlogContext.Provider value={{ ...state, dispatch }}>
            {children}
        </BlogContext.Provider>
    );
};

this is my context code when in frontend i clicked the delete icon <div> needs disappear but it doesn't disappear when i refresh the page it disappear but it leads that react context is not working properly i don't what is problem in this code if you offer an help it is appreciated

this full code for the project: https://github.com/ArunM037/Retro_Blog-Using-Mern-Stack

I'm expecting that the context working properly when I click the delete button the <div> disappear real-time by not refreshing the page


Solution

  • You're duplicating your blogs state in both the BlogContext...

    const [state, dispatch] = useReducer(BlogsReducer, {
      blogs: null
    });
    

    and the Home component...

    const [blogs, setBlogs] = useState(null);
    

    These are completely separate objects. Making changes to one won't effect the other.

    The simplest solution is to only use your context state.

    Remove the local state from Home and use blogs from useBlogContext()...

    const { blogs, dispatch } = useBlogContext();
    

    You can even do the same in your Blogs component so there's no need to pass the blog prop.


    I would also highly recommend initialising your state with an empty array instead of null. This way you can avoid constantly checking for null values

    const [state, dispatch ] useReducer(BlogsReducer, {
      blogs: [],
    });