2

I am trying to implement a feature in my project where I can like and unlike a post. I am working with NodeJs, Express, and MongoDB for back-end and ReactJs and axios on front-end The problem is that my DB is updating real-time when I hit the like/unlike button but on front-end, it's one render behind. Bellow you have some snippets of my code:

NodeJS

exports.likePost = catchAsync(async (req, res, next) => {
  const post = await Post.findByIdAndUpdate(
    req.params.id,
    {
      $push: { likes: req.user._id },
    },
    {
      new: true,
    }
  );

  if (!post) {
    return next(new AppError('No post found with that ID', 404));
  }

  res.status(200).json({
    status: 'success',
    data: {
      post,
    },
  });
});

exports.unlikePost = catchAsync(async (req, res, next) => {
  const post = await Post.findByIdAndUpdate(
    req.params.id,
    {
      $pull: { likes: req.user._id },
    },
    {
      new: true,
    }
  );

  if (!post) {
    return next(new AppError('No post found with that ID', 404));
  }

  res.status(200).json({
    status: 'success',
    data: {
      post,
    },
  });
});

Context State

  const initialState = {
    user: null,
    currentPost: null,
    posts: null,
    trending: null,
    newest: null,
    error: null,
    currentPostLiked: null,
  };

  const likePost = async (postId) => {
    try {
      const res = await axios.patch(`/api/v1/posts/${postId}/like`, null, {
        headers: { Authorization: 'Bearer ' + localStorage.getItem('token') },
      });

      dispatch({
        type: LIKE_POST,
        // payload: res.data.data.post.likes,
      });
    } catch (err) {
      console.log(err);
    }
  };

  const unlikePost = async (postId) => {
    try {
      const res = await axios.patch(`/api/v1/posts/${postId}/unlike`, null, {
        headers: { Authorization: 'Bearer ' + localStorage.getItem('token') },
      });

      dispatch({
        type: UNLIKE_POST,
      });
    } catch (err) {
      console.log(err);
    }
  };

Context Reducer

case LIKE_POST:
  return {
    ...state,
    currentPostLiked: true,
  };
case UNLIKE_POST:
  return {
    ...state,
    currentPostLiked: false,
  };

POST COMPONENT

const PostItem = ({ post }) => {
  let currentPost = post;

  const authContext = useContext(AuthContext);
  const postContext = useContext(PostContext);

  const { currentUser } = authContext;
  const { likePost, unlikePost, currentPostLiked } = postContext;

  const [liked, setliked] = useState(false);

  useEffect(async () => {
    if (currentUser) {
      const currentLiked = post.likes.includes(currentUser.id);
      if (currentLiked) {
        const likedPost = await axios.get(`/api/v1/posts/${post.id}`);
        currentPost = likedPost.data.data.post;
        console.log('LIKED POST', likedPost);
        // setliked(true);
      }

      if (!currentLiked) {
        const likedPost = await axios.get(`/api/v1/posts/${post.id}`);
        currentPost = likedPost.data.data.post;
        console.log('UNLIKED POST', likedPost);
        // setliked(false);
      }
    }
  }, [currentPostLiked]);

  const onLikePost = () => {
    if (liked) {
      unlikePost(post.id);
      setliked(false);
    }
    if (!liked) {
      likePost(post.id);
      setliked(true);
    }
  };

  const likeUnlike = liked ? 'fas fa-heart' : 'far fa-heart';

return (
            <Likes onClick={onLikePost}>
              <i className={likeUnlike} /> {currentPost.likes.length}
            </Likes>
)

I have to let you know that I am a beginner and it might be a small logical mistake but I cannot figure it out, and the code looks a bit messy because I was trying a lot of approaches. Thank you guys for your time

Adrian
  • 65
  • 7
  • 1
    There is a lot of code here, but any "1 render behind" React issue has a good chance of being a state that is used before it has finished setting. – DBS Apr 20 '21 at 12:17
  • 1
    Does this answer your question? [React setState not updating state](https://stackoverflow.com/questions/41446560/react-setstate-not-updating-state) – pilchard Apr 20 '21 at 13:42

0 Answers0