본문 바로가기

공부/프로젝트

[팀 프로젝트] 방콕스타일 - 좋아요 기능 구현

반응형

좋아요 기능 구현 이유 ✨

사용자 참여 유도

`좋아요` 버튼을 통해 간단한 클릭만으로 콘텐츠에 대한 피드백을 제공할 수 있고 댓글 작성보다 간편해 사용자들이 자주 상호작용할 수 있게 만들기 위해 구현을 하기로 결정했습니다.

 

구현 📖

 

`getAllData`메서드를 비동기로 실행해 게시물 데이터를 가져옵니다.

const response = await getAllData()

 

 

`supabase`에서 데이터를 가져올 때 posts 테이블과 likes 테이블을 조인해 사용자가 좋아요를 누른 게시물에 대한 정보를 함께 가져와 반환합니다.

const getAllData = async () => {
  try{
    // 전체 게시글 데이터 가져오기
    const response = await supabase
      .from("posts")
      .select("*, likes(post_id)")
      .order("created_at", { ascending: false })
      
    return response
  } catch (error) {
    console.error("게시글 데이터를 가져오지 못했습니다.", error);
  }
}

export default getAllData;

 

반환받은 `response`를 formattedLikeData 메서드에 넘겨줍니다.

const data = formattedLikeData(response)

 

`formattedLikeData` 메서드에서 좋아요 한 게시물이 있다면 true, 아니면 false를 반환해 `isLiked`라는 속성에 값을 할당합니다.

const formattedLikeData = (response) => {
  return response.data.map(post => ({
    ...post,
    isLiked: post.likes ? post.likes.some(like => typeof like.post_id === 'number') : false
  }))
}

export default formattedLikeData;

 

`data`를 컨텍스트에 저장합니다.

// 전체 게시글 데이터 저장
setAllPosts(data);

// 실제 화면에 보여줄 데이터 저장
setDisplayedPosts(filteredDisplayedPostsData(LIMIT_NUMBER, data));

 

화면을 그릴 때 `isLiked` 속성이 true/false여부에 따라 좋아요 이미지를 활성화 시킵니다.

const PostCard = ({ post, userInfo, onUnlike }) => {
  const { id: post_id, img_url, isLiked, title, hash_tag, content } = post;
  const [isLike, setIsLike] = useState(isLiked);

  // 게시글 보여주기
  const postCard = (
    <Links>
      <PostWrapper>
        <PostImageWrapper>
          <PostImage src={img_url} />
        </PostImageWrapper>
        <PostTitle>
          <Title>{title}</Title>
          <LikeIcon onClick={toggleLike}>
            {!isLike ? <Like width="24" height="24" /> : <LikeActive width="24" height="24" />}
          </LikeIcon>
        </PostTitle>
        <PostHashTag>{hash_tag}</PostHashTag>
        <PostContent>{content}</PostContent>
      </PostWrapper>
    </Links>
  );

 

이후 좋아요 이미지를 클릭했을 때 로그인을 했다면 `updateLikeStatus`메서드를 실행, 비로그인이라면 로그인 페이지로 이동시킵니다.

const toggleLike = async () => {
  if (!userInfo) {
    alert("로그인이 필요합니다.");
    return navigate("/sign-in");
  }

  setIsLike(!isLike);
  await updateLikeStatus(post_id, userInfo.id, isLike);
};
  
  
<LikeIcon onClick={toggleLike}>
  {!isLike ? <Like width="24" height="24" /> : <LikeActive width="24" height="24" />}
</LikeIcon>

 

`isLike`상태를 통해 좋아요 게시물을 서버에 업데이트 및 삭제를 합니다.

const updateLikeStatus = async (post_id, user_id, isLike) => {
  try {
    if (!isLike) {
      const { data } = await supabase.from("likes").insert({ post_id: post_id, user_id: user_id });
    } else {
      const { data, error } = await supabase.from("likes").delete().eq("post_id", post_id).eq("user_id", user_id);

      if (error) throw error;
    }
  } catch (error) {
    console.error("좋아요 업데이트에 실패했습니다.", error);
  }
};

export default updateLikeStatus;

 

supabase 추가 삭제

 

잘 반영된 걸 볼 수 있습니다!

어려웠던 점 ❓

링크

 

회고 🧐

사용할 땐 되게 편하게 사용했는데 직접 구현하려고 하니까 신경 써야 될 부분이 많아서 힘들었던 것 같습니다.ㅜㅜ

아직 많이 부족하기 때문에 조언은 언제나 환영입니다~!

 

 

반응형