Notice
Recent Posts
Recent Comments
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

HYEWON JUNG의 개발일지

20240123 TIL 추천기능 추가하기 본문

개발일지

20240123 TIL 추천기능 추가하기

혜won 2024. 1. 25. 04:05

커뮤니티에는 어쩌면 당연하게 추천기능이 있어야하는데 간단하게 로직을 생각해봤을 때 

 

1. 추천 버튼을 누르면 추천버튼에 색이 들어가고 게시글에 좋아요가 1 늘어나고 좋아요한 유저 기록하기

2. 추천 버튼을 다시한번 누르면 추천버튼에 색이 사라지고, 좋아요가 1줄어들고 좋아요한 유저에서 지우기

 

이렇게 인데 그러면 state가 하나 있어야겟네?  liked라는 state를 만들어줬다. liked인 이유는 원래는 좋아요가 위치했었기때문.. 리네임 해야겠다 .    

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

그러면  우선 liked 여부에 따라 아이콘을 바꿔주는 로직이 있어야겠지?

        <div>
          {liked ? <St.LikesIconOn /> : <St.LikesIcon className="likes" />}
        </div>

이제 본격적으로 로직을 짜보자!

우선 상세페이지에 들어갈 때 유저가 좋아요를 눌렀는지 안눌렀는지 확인을 해야겠지?

  useEffect(() => {
    // 사용자가 이미 좋아요를 했는지 확인
    const userLiked = posts?.[0]?.likes_user?.includes(userId);
    if (userLiked) {
      setLiked(true);
    }
  }, [posts, userId]);

수많은 물음표를 뒤로한채 설명을 해보자면.. posts= 해당게시물, likes_user = 게시물에 좋아요한 유저, userId= 현재 접속한 유저 , 해당게시물에  좋아요한 유저 목록에 현 유저가 포함되어 있다면 liked를 true로 만드는 로직이다! 이건 만약에 유저가 바뀌거나, 게시물이 바뀔 때마다 변경을 줘야하기때문에 의존성 배열에 posts 와 userId를 둔다. 

 

이제 추천이 토글되는 로직을 짜보자!

  const toggleLike = async () => {
    const newLikedStatus = !liked;
    setLiked(newLikedStatus);

    // 기본값으로 빈 배열 설정
    const currentLikeUsers = posts![0]?.likes_user || [];


  };

현재 liked 상태의 반대를 newLikedStatus로 선언을 하고 현재 좋아요를 누른 유저목록을 선언을 해주는데 이 코드에서는 posts의 liked-user가 없으면 빈 배열을 가지도록 설정을 했는데 나같은 경우엔 db에 이미 디폴트 값으로 빈 배열을 두었기 때문에 필요하진 않다. 

 

하지만 데이터를 가져오는 속도보다 함수를 먼저 파싱해버리면 아마도 filter오류가 날 것이다.

    const updatedLikes = newLikedStatus ? likes! + 1 : likes! - 1;

위에서 선언한 newLikedStatus가 참이면 likes 에 +1을 거짓이면 -1을 해줄것

    let updatedLikeUsers;
    if (newLikedStatus) {
      updatedLikeUsers = [...currentLikeUsers, userId];
    } else {
      updatedLikeUsers = currentLikeUsers.filter((id: string) => id !== userId);
    }

updatedLikeUsers를 밖에서 선언한 이유 !

자바스크립트의 블록스코프때문이다. 만약 if문 안에서 선언을 하게 된다면 if문 안에서만 사용을 할 수 있게 되기 때문에 db에 넣어주는 로직에서도 써주어야해서 밖에서 선언을 해주었다. 

조건문은 newLikedStatus가 참이면 updatedLikeUsers는 원래 유저목록에 현재 유저를 추가하고 아니면 현재 목록에서 현재 유저를 제거 해준다. 

    const likesUpdate = {
      updateData: {
        likes: updatedLikes,
        likes_user: updatedLikeUsers
      },
      paramId
    };
    upsertMutation.mutate(likesUpdate);

그리고 db에 올려주는 로직!