Today I Learned

Parkboss·2023년 1월 30일
0

내일배움캠프

목록 보기
80/120
post-thumbnail

오늘 한일✅

  • 좋아요 기능을 구현했다.

시도해본 것들✅

이번 프로젝트의 좋아요 기능은 일반적인 좋아요 기능과는 달랐다.
기존의 db에 들어가서 isLike을 true 또는 false로 바꿔주는 경우가 대부분이다.
하지만! 우리 프로젝트는 유튜브 Api를 불러오기 때문에 파이어베이스에 일일이 저장할 수 없는 상황이였다.
그래서 좋아요 버튼을 추가할때(addDoc) 유저 아이디 뿐만 아니라 videoId도 같이 파이어베이스에 추가하여 userId와 videoId가 일치하면 Mypage에 들어가게끔 구현하였다.


1. 데이터 넘기는 방법

  • 데이터를 navigate hook을 사용해 넘기는 방법으로 사용했다.
<Wrapper onClick={() => {
        navigate(`${item.id.videoId}`, { state: { item } });
      }}
    >
  • useLocation hook을 사용해 state의 item을 받아왔다.
const {state: { item },} = useLocation();
  • 부모 자식인 Youtube.tsx에서 Like.tsx에 필요한 정보들을 props로 내려준다.
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을 받아준다.

2. addDoc

  • 파이어베이스에 영상 정보 + 유저 아이디 + isLike : true 로 추가

// 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);
  };

문제점✅

3. getDocs

  • 🚧 좋아요 기능에서VideoIduserId 가 일치하면 그 데이터를 가져오는 부분에서 에러를 만났다.

첫 번째 방법

  • where 을 두 번 사용하여 userIdvideoId가 같으면 정보를 가져오는 부분에서 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실행 아니면 false

  • 위 코드로 변경하고 userIdvideoId 값이 잘 출력이 된다!

4. deleteDoc

  // 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 />}

알게 된점✅

  • 팀원분 덕분에 좋아요 기능 구현을 이해하면서 코드를 짤 수 있었다.
profile
ur gonna figure it out. just like always have.

0개의 댓글