인피니티 스크롤을 구현하기 위해서는 보통 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>)
이런 식으로 해서 인피니티 스크롤을 구현할 수 있었다.