본문 바로가기

🌼 TIL

저장(좋아요)기능 구현- Next.js, Firebase

구현할 것

- 게시물 저장(책갈피) 기능

- 저장한 게시물 

 

기능개발 이유

: 마음에 드는 게시물들을 저장하여 유저 사용성 개선

 

기능 구현

//! 저장할 게시물의 데이터를 firestore에 저장하는 코드


//* collection 저장 토글 state
  const [isCollect, setIsCollect] = useState(true);
  
  //* mutation 사용해서 collector값 보내기
  const { mutate: onAddCollection } = useMutation<
    undefined,
    undefined,
    ItemType
  >(addCollectionData, {
    onSuccess: () => {
      setTimeout(() => queryClient.invalidateQueries('collectiondata'), 500);
    },
    onError: () => {},
  });
  
  //* collection 저장 기능입니다.
  const onClickCollection = () => {
    onAddCollection({
      ...item,
      uid: postId,
      collector: authService.currentUser?.uid,
      imgUrl: imgUrl,
      town: town,
    });
    setIsCollect(!isCollect);
  };
  
  
  
  //* useEffect로 collection 상태 예외처리 하기
  useEffect(() => {
    if (collectorUid?.indexOf(collector) > -1) {
      setIsCollect(false);
    } else {
      setIsCollect(true);
    }
  }, [collectorUid, collector]);

  if (isLoading) return <h1>로딩중 입니다</h1>;
  if (isError) return <h1>통신이 불안정합니다</h1>;
  ) {
    return (
      <CollectionContainer>
        {collectorUid ? (
          <CollectionText>{collectorUid.length}</CollectionText>
        ) : (
          0
        )}
        {isCollect ? (
          <CollectionBtn onClick={onClickCollection}>
            <Image src="/before_save.svg" alt="image" width={30} height={30} />
          </CollectionBtn>
        ) : (
          <CollectionBtn onClick={deleteCollection}>
            <Image src="/save_icon.svg" alt="image" width={30} height={30} />
          </CollectionBtn>
        )}
      </CollectionContainer>
    );
  }
- useMutation을 이용하여 firestore에 마음에 들어 저장한 게시물의 데이터를 업데이트
- 데이터를 추가,삭제할 때 비동기적으로 작업을 하기 위해 setTimeout을 적용
- useState를 사용하여 상태관리
- useEffect로 상태를 예외처리를 주어 유저 사용성 개선

이후 useQuery를 활용하여 저장한 게시물의 종류별로 화면에 표시하는 GET요청을 하였다.

여기서 한가지 문제점이 있었다.(짧게 설명)

문제점 

데이터를 불러올 때 필요없는 데이터도 불러와 비효율적인 데이터 요청이 발생하였다.

해결

useQuery의 select옵션을 사용할 수 있었지만 비효율적인 초기 데이터모델링을 수정하는 방법을 선택

참고 : https://fullbackgee.tistory.com/104

 

다시 돌아와 useQuery를 활용하여 GET요청을 하였다.

 

//* useQuery 사용해서 collection 데이터 불러오기
  const {
    data: collectionData,
    isLoading,
    isError,
  } = useQuery('collectiondata', getCollection);

  //* 만든 것 중 town 값만 고르기
  const myCollectPost = data?.filter((item: { town: string }) => {
    return item.town;
  });
  //* town값을 골라 map 돌리기
  
const Town = ({ value, myPostData }: { value: string; myPostData: any }) => {
  const [more, setMore] = useState(true);

  // * 내 게시물 town 추출
  const myPostTownList = myPostData?.filter((item: any) => item.town === value);
  ){
  return(
  <div>
  	<MySpotImg>
      <Masonry columnsCount={2} style={{ gap: '10px' }}>
      	{myPostTownList?.map((item: { [key: string]: string }) => (
          	<MyCollectItem key={uuidv4()} item={item} />
       	))}
      </Masonry>
    </MySpotImg>
  </div>
  );
  }

 

 

 

결과

마음에 드는 게시물 저장기능(좋아요 기능)