Search code examples
javascriptreactjsreduxredux-toolkit

Why isn't component being updated through useEffect?


I can't see <PostWidget/> in the UI for below code.

PostsWidget.jsx

import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { setPosts } from "../../../Redux/Slices/authSlice";
import PostWidget from "../PostWidget";
import { userRequest } from "../../../requestMethod";

const PostsWidget = ({ userId, isProfile = false }) => {
  const dispatch = useDispatch();
  const posts = useSelector((state) => state.posts);
  console.log("posts", posts);

  const getPosts = async () => {
    const res = await userRequest.get("/posts");
    console.log("all Posts", res.data);
    dispatch(setPosts(res.data));
  };

  const getUserPosts = async () => {
    const res = await userRequest.get(`/${userId}/posts`);
    console.log("user Post", res.data);
    dispatch(setPosts(res.data));
  };

  useEffect(() => {
    if (isProfile) {
      getUserPosts();
    } else {
      getPosts();
    }
  }, []);

  return (
    <>
      {posts && posts.map(
        ({
          _id,
          userId,
          firstName,
          lastName,
          description,
          location,
          picturePath,
          userPicturePath,
          likes,
          comments,
        }) => (
          <PostWidget
            key={_id}
            postId={_id}
            postUserId={userId}
            name={`${firstName} ${lastName}`}
            description={description}
            location={location}
            picturePath={picturePath}
            userPicturePath={userPicturePath}
            likes={likes}
            comments={comments}
          />
        )
      )}
    </>
  );
};

export default PostsWidget;

PostWidget.jsx

const PostWidget = () => {
  return (
    <div>
      <h4>Post Widget</h4>
    </div>
  );
};

export default PostWidget;

Here, userRequest is an axios method. I wrote two functions getPosts and getUserPosts to call the API

AuthSlice.js

import { createSlice } from "@reduxjs/toolkit";
const initialState = {
  mode: "light",
  user: null,
  token: null,
  posts: [],
};      
export const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {                 
 setPosts: (state, action) => {
      state.posts = action.payload.posts;
    },
    setPost: (state, action) => {
      const updatedPosts = state.posts.map((post) => {
        if (post._id ===action.payload.post._id) {
          return action.payload.post;
        }
        return post;
      });
      state.posts = updatedPosts;
    },
  },
});

I checked the console.logs and also redux state with the redux devtool. Both are showing upadated posts. console.log

all Posts (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}]


Solution

  • The code is updating the state.posts in wrong way. Since setPosts: (state, action) => { state.posts = action.payload.posts; }, Need to update the code as follows:

    PostsWidget.jsx

      const getPosts = async () => {
        const res = await userRequest.get("/posts");
        console.log("all Posts", res.data);
        dispatch(setPosts({ posts: res.data }));
      };
    
      const getUserPosts = async () => {
        const res = await userRequest.get(`/${userId}/posts`);
        console.log("user Post", res.data);
        dispatch(setPosts({ posts: res.data }));
      };