useInfiniteQuery를 다음과 같이 사용했다
const { data, fetchNextPage, isLoading, hasNextPage } = useInfiniteQuery({
queryKey: ['animalPictureInfinite'],
queryFn: ({ pageParam }) => fetchAnimalPost(pageParam),
initialPageParam: 1,
getNextPageParam: (lastPage, allPages, lastPageParam) => {
return lastPageParam + 1
},
select: data => ({
pages: data.pages.flatMap(page => page),
pageParams: data.pageParams,
}),
refetchOnMount: false,
refetchOnReconnect: false,
refetchOnWindowFocus: false,
})
select는 받아온 데이터에서 변형을 할 수 있게 하는 옵션인데 여기서는 flatMap을 사용했다 그 이유는 페이지당 받아온 데이터는 배열인데 flatMap을 사용 안하면 배열안의 배열 즉 이차 배열 형태로 이루어져 있어 평탄화 작업을 진행했다.
그리고 refetchOnMount, refetchOnReconnect, refetchOnWindowFocus를 false를 한 이유는 stale일 때 위와같은 속성이 true가 되면 데이터를 다시 불러오기 때문이다. 그래서 일단은 false를 해놓은뒤 데이터를 안불러오게 했다.
const handleObserver: IntersectionObserverCallback = useCallback(
entries => {
const [target] = entries
if (target.isIntersecting && hasNextPage) {
fetchNextPage()
}
},
[fetchNextPage, hasNextPage],
)
const element = observerElem.current
const option = {
root: null,
rootMargin: '0px',
threshold: 1,
}
const observer = new IntersectionObserver(handleObserver, option)
if (element) observer.observe(element)
return () => {
if (element) observer.unobserve(element)
}
IntersectionObserver를 통해 마지막 페이지의 맨 끝에 element가 감지되면 페이지를 불러오게 하는 방법이다. handleObserver는 IntersectionObserver 인스턴스의 콜백 함수이다.
아직 공부겸 사용해본 useInfiniteQuery라 좀 더 공부를 해봐야할 것 같다. 특히 useSuspenseInfiniteQuery를 이용해 skeleton UI를 만들어 봐야할 것 같다