이번 프로젝트의 좋아요 기능은 일반적인 좋아요 기능과는 달랐다.
기존의 db에 들어가서isLike
을 true 또는 false로 바꿔주는 경우가 대부분이다.
하지만! 우리 프로젝트는 유튜브 Api를 불러오기 때문에 파이어베이스에 일일이 저장할 수 없는 상황이였다.
그래서 좋아요 버튼을 추가할때(addDoc) 유저 아이디 뿐만 아니라videoId
도 같이 파이어베이스에 추가하여 userId와 videoId가 일치하면 Mypage에 들어가게끔 구현하였다.
navigate hook
을 사용해 넘기는 방법으로 사용했다.<Wrapper onClick={() => {
navigate(`${item.id.videoId}`, { state: { item } });
}}
>
useLocation hook
을 사용해 state의 item
을 받아왔다.const {state: { item },} = useLocation();
Youtube.tsx
// 디테일 페이지에서 보여지는 동영상 정보들
const {
title,
channelTitle,
publishTime,
description,
channelId,
thumbnails,
} = item.snippet;
// Likes에 필요한 아이들을 props 내려준다.
<Likes
title={title}
channelTitle={channelTitle}
channelId={channelId}
thumbnails={thumbnails}
date={date}/>
addDoc
에 필요한 데이터를 props
을 받아준다.
// 1. 하트 클릭 시 addDoc에 영상 정보와 isLike 추가
const addLike = async () => {
// 로그인 체크 ( 로그인 이동하는거 추가/ alert 창 )
if (!authService.currentUser) {
alert('로그인이 필요합니다.');
navigate('/login');
}
await addDoc(collection(dbService, 'likes'), {
title,
channelTitle,
channelId,
videoId,
thumbnail,
publishTime: date,
isLike: true,
userId: authService.currentUser?.uid,
});
setLike(true);
};
VideoId
와 userId
가 일치하면 그 데이터를 가져오는 부분에서 에러를 만났다.where
을 두 번 사용하여 userId
와 videoId
가 같으면 정보를 가져오는 부분에서 undefined
가 뜬다
공식 문서에서 where
를 두 번 사용할 수 없다는 글을 보았다. 😂😂😂
위에 공식 문서를 참고하고 stackoverflow 에서 힌트를 얻어 query
를 두번 사용하여 q
, q2
로 나누어 할당하였다.
📍 그러나! Uncaught TypeError: doc.data is not a function 오류가 뜸
doc.data
의 오류를 잡기위해 다양한 방법을 사용해 봤지만 코드는 더 복잡해져갔다.
팀원분이videoId
를 걸러주는filter
를 함수로 따로 빼서 사용하자고 했다.
클릭한 item.videoId
와 db의 likes 문서에 있는 videoId
와 같은 친구들만 걸러서 할당
selectedArray
의 빈배열에 likeObj
의 정보들을 push해준다.
changeIikedetail
의 함수에 selectedArray
을 인자로 넘겨줘서 filter를 거쳐서 내가 클릭한 영상의 아이디 값만 filteredlike
에 할당된다.filteredlike
를 전역에서 사용할 수 있게 setchckedItem
에 넘겨준다.filteredlike
의 길이가 0보다 크면 true실행 아니면 falseuserId
와 videoId
값이 잘 출력이 된다! // 3.채워진 하트 클릭 시 deleteDoc
const isLikeChangeHandler = async () => {
if (like) {
await deleteDoc(doc(dbService, 'likes', checkedItem[0].id));
setLike(false);
}
};
// useState의 like의 true, false값에 따라 함수와 하트가 달라진다.
<HeartWrapper
onClick={() => (like ? isLikeChangeHandler() : addLike())}>
{/* 좋아요 유무 */}
{like ? <LikeBtnFill /> : <LikeBtnLine />}