ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 무한스크롤 커스텀 hook
    코드잇 2024. 6. 10. 21:12

    서문

    이전의 포스팅 중 하나인 [BLOB] 프로젝트 회고의 프로젝트에서 무한스크롤 구현하면서 발생한 문제와 이를 해결한 방식을 담고 있습니다.

     

    구현

    무한스크롤

    데이터 가져오는 과정과 로딩 및 에러 처리를 쉽게 구현하기 위해 React Query의 useInfiniteQuery 훅 이용

    ViewPort에 보여지는 요소를 체크하기 위해 react-intersection-observer의 useInView 훅 이용

     

     

    처음 무한스크롤 훅 코드 부분

    export default function useInfiniteQueries(variant: 'feedPage') {
      const queryKey = [variant];
      let queryFn;
    
      // variant에 따라 다른 queryFn을 사용
      if (variant === 'feedPage') {
        // eslint-disable-next-line prefer-const
        queryFn = ({ pageParam = 0 }) => getPosts(pageParam, POSTS_PAGE_LIMIT);
      }
    
      const {
        data: postsData,
        isPending,
        isError,
        fetchNextPage,
        isFetchingNextPage,
      } = useInfiniteQuery({
        queryKey,
        queryFn,
        initialPageParam: 0,
        getNextPageParam: (lastPage, allPages, lastPageParam: number) => (lastPage.hasMore ? lastPageParam + 1 : undefined),
      });
    
      return { postsData, isPending, isError, fetchNextPage, isFetchingNextPage };
    }

     

     

    페이지 별로 다른 queryFn을 설정해서 무한스크롤 훅을 구현했었다.

     

    이후 팀원에게 코드 리뷰를 받았고, 

     

     

    페이지가 많아질 경우 코드가 길어지는 문제를 해결할 필요가 있었다.

     

    if문에 queryFn은 다른 곳에서 처리하고 무한스크롤 훅 부분에서는 무한스크롤에 관련된 코드만 작성하도록 했다.

    export default function useInfiniteScrollQuery(queryOptions: {
      queryKey: readonly (string | number)[];
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      queryFn: (page: number) => Promise<any>;
    }) {
      const { queryKey, queryFn } = queryOptions;
    
      const { ref, inView } = useInView();
    
      const { data, isPending, isError, fetchNextPage, isFetchingNextPage, refetch } = useInfiniteQuery({
        queryKey,
        queryFn: ({ pageParam }) => queryFn(pageParam),
        initialPageParam: 0,
        getNextPageParam: (lastPage, allPages, lastPageParam: number) =>
          lastPage.data.hasMore ? lastPageParam + 1 : undefined,
      });
    
      useEffect(() => {
        if (inView) {
          fetchNextPage();
        }
      }, [inView, fetchNextPage]);
    
      return { data, isPending, isError, fetchNextPage, isFetchingNextPage, ref, refetch };

     

     

    무한 스크롤 hook 사용 부분 

    export function useFetchNotificationList() {
      return useInfiniteScrollQuery({
        queryKey: notifications.all.queryKey,
        queryFn: (page: number) => getNotificationList({ page, size: POSTS_PAGE_LIMIT }),
      });
    }

     

    거의 모든 게시글과 댓글에서 무한 스크롤이 적용된다. 그렇기 때문에 어디서든 무한 스크롤을 사용할 수 있게 훅을 잘 만들어 두는게 중요했다. 어떻게 하면 팀원들이 무한스크롤 훅을 가져가서 잘 쓸 수 있을까? 어떻게 하면 코드 수를 줄일 수 있을까? 팀원들이 이해하기 쉽도록 구현하려고 노력했다. 

    댓글

Designed by Tistory.