파이어베이스에서 useInfiniteQuery 사용하기(react-query)

issue
블로그 이미지

이챙(leechaeng)

﹒2023. 4. 17.

댓글기능을 만드는데 파이어베이스를 db로 사용하고 react-query로 비동기 요청을 사용했다.
댓글에 인피니트 스크롤을 적용하기위해 리액트쿼리의 useInfiniteQuery를사용하게 되었다.
리액트쿼리에서 제공하는 useInfiniteQuery 는 인피니트스크롤 편하게 하라고 만들어 놓은게 아닐까 생각....ㅎㅎ 🤔
useQuery를 무한적으로 불러오고 싶을때 사용하면 된다.

//hook

const useGetComment = async ({ postId, pageParam }: Tdata) => {
  const commentData: Tcomment[] = [];

  try {
    const commentRef = collection(db, 'comment');

    const doc = query(
      commentRef,
      orderBy('timestamp'),//정렬
      where('postId', '==', postId),//postId가 맞는 댓글만 불러오기
      startAfter(pageParam.timestamp ?? 0),//어떤 데이터를 기준으로 가져올껀지
      limit(10),//가져올 데이터 개수
    );

    const querySnapshot = await getDocs(doc);

    querySnapshot.forEach(doc => {
      commentData.push(doc.data() as Tcomment);
    });
    return commentData;
  } catch (error) {
    throw error;
  }
};

export default (postId: string) =>
  useInfiniteQuery(
    ['comments'],
    ({ pageParam = 0 }) => useGetComment({ postId, pageParam }),
    {
      cacheTime: Infinity,
      suspense: true,
      getNextPageParam: lastData => {
        if (lastData?.length! < 10) return undefined; //이전 데이터가 10게 미만이면 리턴
        return lastData?.[lastData.length - 1]; //이전 데이터의 마지막값 리턴
      },
    },
  );


나는 hook으로 만들어서 사용했다.

useInfiniteQuery에서는 getNextPageParam,pageParam만 이해하면 쉽게 사용 가능한거 같다.
getNextPageParam 요청이 완료된후 이전 페이지의 데이터를 불러와준다. 만약 스크롤을 하다가 다음 데이터를 불러와야 할때 이전 데이터의 값을 알려준다. 이 데이터가 lastData에 담긴다. 그 데이터를 기준으로 다음데이터를 불러올지 말지 결정하면 된다.
난 10개씩 데이터를 불러오게 했으므로 이전 데이터가 10개 미만이면 이미 불러올 데이터는 없으므로 undefined를 리턴한다.
10개 이상이면 다음 데이터를 또 불러오겠쥬!
다음 데이터를 불러오기 위해선 마지막 값을 기준으로 불러와야 하기 때문에 리턴해준다.
근데 내가 작업하다가 궁금했던게 그럼 그 마지막값이 useGetComment함수에 어떻게 리턴되는데??!!!!!!!!!!!!!!!!!!!!!!!!!!!! 이것때문에 사실 헤맸음 ㅎ..
pageParam 파라미터에 담김. 신기하게 저기로 담겨서 옴. 그래서 난 개쩐다라는 생각을 했음.


이제 파베 쿼리 startAfter에 pageParam으로 기준을 넣어주면 알아서 다음 데이터가 불러와짐 api요청은 이게 끝!!!


  //commentList.tsx
  
  const CommentList = ({ postId, me }: CommetListProps) => {
 
  const {
    data: commentData,
    isLoading: commentLoading,
    fetchNextPage,
  } = useGetComment(postId as string);
  
  ....
  
  
  useInfinityScroll(() => { //ui 인피니트 스크롤 훅
    fetchNextPage();
  });

  if (commentLoading) alert('로딩중 입니다.');
  
  
  ....
  
  return (...)
  
  }


쿼리 훅을 사용한 컴포넌트를 확인해보면 인피니트 스크롤 훅 만들어 놓은 곳에 fetchNextPage함수를 넣어줬다.

스크롤 했을때 다음페이지를 불러오는 것!!!!! 완전 대박 아니냐며,,ㅎㅎ

리덕스 같은걸로 인피니트 스크롤 사용하면 쫌 복잡한데 리액트쿼리에서 제공하는 useInfiniteQuery를 사용하니 간단했다. 알아서 다음데이터 이전데이터 계산해서 불러와주니,,,안사용할 이유가 있을까,,,왕따봉!!

이챙(leechaeng)
이챙(leechaeng)

프론트엔드 개발도 하고 뛰기도 하고

'issue' 카테고리의 관련 글