카테고리 없음

[nestJS]무한스크롤 지원하기

변기원 2023. 3. 26. 20:44

프런트엔드는 react-query의 useInfiniteQuery를 사용해서 무한스크롤을 구현했다.

const useGetReviews = (params?: ParsedUrlQuery) => {
  return useInfiniteQuery(
    reviewKeys.reviewLists(),
    ({ pageParam = 0 }) =>
      reviewAPI.getReviews({ page: pageParam, size: '10', ...params }),
    {
      getNextPageParam: ({ nextPage }) => nextPage,
      select: (data) => {
        const infinityData = extractInfinityDataFromDeep(data, 'items');

        return { pageParams: [], pages: infinityData };
      },
    }
  );
};

위 훅을 사용하는 컴포넌트는

const { data, fetchNextPage, hasNextPage, isError, isFetching, isLoading } =
    useGetReviews();
    
return (
    <div>
      {data?.pages.map((review, index) => {
        return (
          <div key={index}>
            <ReviewCard review={review} />
            <HorizonDivider lineColor="gray100" />
          </div>
        );
      })}
      <Observer ref={target} />
    </div>
  );

useInfiniteQuery가 반환하는 hasNextPage와 isFetching을 이용해서 다음페이지를 불러온다.

그러면 useInfiniteQuery가 다음페이지가 있는지, 없는지 어떻게 알게 할까?

위와 같은 방법으로 하면 된다. 답변을 주신 분은 getNextPageParam의

인자로 받는 데이터중에 pages의 길이에 +1 한 것을 다음페이지 번호로 해서 재요청을 하는 방식이다.

나의 프론트 코드는 서버에서 보내준 nextPage데이터를 받아서 그대로 queryFn의 인자로 넘기기 때문에

백엔드에서 nextPage만 정확히 보내주면 된다.

 

nestJS의 레포지토리 코드이다.

async getAllReviews(page: number, size: number) {
    const total = await this.reviewModel.count();
    if (Math.ceil(total / size) < page) {
      throw new HttpException('please check query string', 400);
    }
    const result = await this.reviewModel
      .find()
      .skip(page * size)
      .limit(size);
    return new Page(total, size, result, page);
  }

사실 페이지네이션 하는 방법과 똑같은데 프론트에서 쓸 nextPage만 잘 추가해 주자

Page클래스를 조금 수정해야 한다.

export class Page<T> {
  pageSize: number;
  nextPage: number;
  hasNextPage: boolean;
  items: T[];
  constructor(totalCount: number, pageSize: number, items: T[], page: number) {
    this.pageSize = pageSize;
    this.items = items;
    this.hasNextPage = Math.ceil(totalCount / pageSize) > page + 1;
    this.nextPage = this.hasNextPage ? page + 1 : null;
  }
}

만약 다음페이지가 있으면, 현재 요청한 페이지 +1을 보내주고 다음페이지가 없으면(방금 요청한 게 마지막이면) null을 보내서

다음페이지 요청을 못하도록 하자.

위 캡처처럼 0페이지 1페이지에서 각각 알맞은 데이터를 내려줬음을 확인할 수 있다! 무한스크롤 구현 끝

 

 

 

https://stackoverflow.com/questions/75123685/how-to-achieve-infinite-scroll-in-react-with-react-query

 

How to achieve Infinite scroll in React with React Query?

I want my API to fetch new data as in increase the page number when I have reached the bottom of the page, basically I want to infinite scroll with React Query. I have literally watched all the vid...

stackoverflow.com