react query 인피니티 스크롤 구현

정지훈·2022년 6월 15일
0

리엑트 쿼리로 인피니티 스크롤 구현하기

인피니티 스크롤을 구현하기 위해서는 보통 js 나 react 같은 경우 제일 하단에 div를 숨겨놓아서

const obserberRef = useRef();
const [obState, setObState] = useState(false);
useEffect(() => {
  const options = {
    threshold: 0.2,
    rootMargin: "0px",
  };

  const observer = new IntersectionObserver(function (entries, observer) {
    entries.forEach((entry) => {
      if (!entry.isIntersecting) {
        return;
      }
      fetchNextPage();
      console.log(entry.isIntersecting);
    });
  }, options);
  observer.observe(obserberRef.current);
}, [fetchNextPage]);

이전 previousData를 array라는 변수에 저장해놓고
intersectionObserver를 이용해 감지를 해서 페이지네이션 처럼 다음 페이지를 호출하여 array라는 변수로 push를 하여 구현할 수 있다.

이렇게 구현할 수 있지만 마지막 페이지가 나온 후 또 호출을 하면 이것또한 구현하기에 힘이 든다.
그래서 react query에서는 useInfiniteQuery 훅을 제공한다.

첫번째 인자로 유니크한 키를 넣고 두번째로는 호출할 promise를 넣는다 마지막으로 3번째로는 옵션을 넣는다.

const {
  status,
  data: infinitData,
  error: infinitError,
  isFetching,
  isFetchingNextPage,
  isFetchingPreviousPage,
  fetchNextPage,
  fetchPreviousPage,
  hasNextPage,
  hasPreviousPage,
} = useInfiniteQuery(
  "projects",
  async ({ pageParam = 0 }) => {
    return await fetchRepositories(pageParam);
  },
  {
    getNextPageParam: (lastPage, allPages) => {
      const maxPage = 14; // 한번에 30개씩 보여주기
      const nextPage = allPages.length + 1; //
      return nextPage <= maxPage ? nextPage : undefined; // 다음 데이터가 있는지 없는지 판단
    },
  }
);

lastPage는 fetch callback의 리턴값이 전달되고 allPage는 배열안에 지금까지 불러온 데이터를 계속 축적하는 형태로 온다. ([[],[]])

옵션에 maxPage (db에 있는 최대갯수) nextPage는 다음 페이지이다.

infinitData를 보면 [[],[]]이런2deps형태라 1deps 로 변경해줘야 한다.

  const filter = infinitData?.pages?.map((item) => item.data);
  console.log(filter?.flat());
  return filter?.flat()?.map(item => <div>{item}</div>)

이런 식으로 해서 인피니티 스크롤을 구현할 수 있었다.

0개의 댓글