Async thunk not updating state

Viewed 508

I'm trying to update an element of a my redux state but I can't make it work. I'm omitting some parts that I think are not necessary

my postSlice is

const INITIAL_STATE = {
  posts: [],
  error: '',
};

...

 builder.addCase(commentPostAsync.fulfilled, (state, action) => {
      const updatedPost = action.payload;
      state = {
        ...state,
        posts: state.posts.map((post) => {
          // console.log(post._id);
          return post._id === updatedPost._id ? { ...post, updatedPost } : post;
        }),
      };
 });

The backend is working ok because if I refresh the page the new comment is in the post as expected.

Action.payload has the post data updated in the backend with the new comment and condition in map function works as expected, because if I move the log inside the condition only logs the right post_id.

So the problem is that { ...post, updatedPost } is not updating the state and I don't know why.

my Feed.jsx component

const Feed = () => {
  const { user } = useSelector((state) => state.auth.user);
  const { posts } = useSelector((state) => state.post);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getTimeLineAsync(user._id));
  }, [dispatch]);

  return (
    <StyledFeed className='feed'>
      <div className='feed__container'>
        <Share />
        {posts &&
          posts?.map((post) => {
            return <Post post={post} key={post._id} />;
          })}
      </div>
    </StyledFeed>
  );
};

export default Feed;

my Post.jsx component

{isOpenComments && (
          <div className='comments__container'>
            <div className='old-comments__container'>
              {post &&
                post.comments.map((comment) => {
                  return <Comment comment={comment} key={comment._id} />;
                })}
            </div>
            <div className='add-comments__container'>
              <div className='add-comments__avatar'>
                {user && <img className='user__avatar' src={user.avatar} alt='' />}
              </div>
              <form className='add-comments__input'>
                <input
                  className='input'
                  type='text'
                  placeholder='Write a comment...'
                  onChange={handleInputChange}
                  name='text'
                />
                <button className='icon' type='submit' onClick={sendComment}>
                  <SendIcon />
                </button>
              </form>
            </div>
          </div>
        )}

UPDATE this is the result of console.log(updatedPost)

{
comments: (18) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
createdAt: "2021-11-25T19:24:40.196Z"
description: "test last "
image: "https://travelprnews.com/wp-content/uploads/2021/11/https___specials-images.forbesimg.com_imageserve_920377840_0x0.jpg"
likes: []
totalComments: 21
updatedAt: "2021-11-27T08:42:17.264Z"
userId: "619a1cc54ac9c7217520e150"
__v: 0
_id: "619fe2f80481f8a4edd791f4"
}

If more info is needed please let me know. Hope that someone can tell me what's wrong with the code.

Thanks in advance

UPDATE SOLVED

I've the solution in this post

builder.addCase(commentPostAsync.fulfilled, (state, action) => {
      const updatedPost = action.payload;
        const index = state.posts.findIndex((post) => post._id === action.payload._id);

        const newArray = [...state.posts];

        newArray[index] = updatedPost;

        return {
          ...state,
          posts: newArray,
        };
1 Answers

The issue here is, you missed destructuring updatedPost. Changing builder case to following should update state as expected (assuming action.payload has post object):

builder.addCase(commentPostAsync.fulfilled, (state, action) => {
      const updatedPost = action.payload;
      state = {
        ...state,
        posts: state.posts.map((post) => {
          // console.log(post._id);
          return post._id === updatedPost._id ? { ...post, ...updatedPost } : post;
        }),
      };
    });

Related