skip to Main Content

I am making Comment’s like/dislike component. I am unable to maintain the state on initial run. It gets undefined on initial run, but state gets updated after pressing like button for second time. Following is my JSX:

<div className="flex justify-between gap-5" onL>
   <h4 className="text-text font-medium text-base">
       {comment?.userID?.name}
   </h4>
   <Button
     className="flex-shrink-0 flex-grow-0"
     onClick={() => {
       setHasLiked((prevHasLiked) => {
           return {
             ...prevHasLiked,
             [comment?.userID?._id]:
             !prevHasLiked[comment?.userID?._id],
             };
           });

           onSubmmitLikeComment(
             comment?._id,
             comment?.userID?._id
            );
           }}
           >
           {hasLiked[comment?.userID._id] ? (
             <Empheart stroke="red" fill="red" />
                ) : (
                  <Empheart stroke="black" fill="black" />
                    )}

                    {comment?.like_count}
           </Button>
         </div>

Following is my onSubmmitLikeComment:

const onSubmmitLikeComment = async (commentID, userID) => {
    console.log("userID", userID); //getiing userID correctly
    const userHasLiked = hasLiked[userID]; //getting undefined in initial click render. But this state gets updated after clicking like button like button for second time
    console.log("userHasLiked", userHasLiked);
    console.log("hasLiked", hasLiked);
    try {
      const response = await fetch("/api/likeComment", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-App-Type": "WEB_APP",
        },
        body: JSON.stringify({ commentID, userID, hasLiked: userHasLiked }),
      });
      const result = await response.json();
      console.log("result", result);
      if (result.isSuccess) {
        setComments((prevComments) =>
          prevComments.map((comment) =>
            comment?._id == commentID && comment?.userID?._id === userID
              ? {
                  ...comment,
                  like_count: userHasLiked
                    ? comment.like_count - 1
                    : comment.like_count + 1,
                }
              : comment
          )
        );
        setHasLiked((prev) => ({
          ...prev,
          [userID]: !userHasLiked,
        }));
      }
    } catch (error) {
      console.error("Unable to update like/unlike comment ", error);
      alert(
        "An error occurred while liking/disliking comment. Please try again."
      );
    }
  };

These are two states being used:

 const [comments, setComments] = useState([]);
const [hasLiked, setHasLiked] = useState({});

2

Answers


  1. enter code here userHasLiked alert

    Login or Signup to reply.
  2. If you can’t maintain state on initial run, it looks like you didn’t set hasLiked correctly on initial run. Make sure the hasLikded state is initialized for each comment when you first fetch the comments. You can use code like this:

    useEffect(() => {
      if (comments && comments.length > 0) {
        const initialHasLiked = comments.reduce((acc, comment) => {
          acc[comment?.userID?._id] = comment?.userHasLiked || false; // Initialize with existing liked status or false
          return acc;
        }, {});
        setHasLiked(initialHasLiked);
      }
    }, [comments]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search