이챙의 개발 log
파이어베이스에서 useInfiniteQuery 사용하기(react-query)
댓글기능을 만드는데 파이어베이스를 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)
프론트엔드 개발도 하고 뛰기도 하고