
기본 세팅은 해당 링크를 참고
<div className="MainPage">
<Header header={'영화'} />
{data.pages.map((page, i) => (
<MovieList key={i} list={page.results} />
))}
<div className="spinner">
<ClipLoader color="#5db996" ref={ref} />
</div>
</div>
useInfiniteQuery 훅 : 여러 페이지의 데이터를 관리하고, 다음 페이지를 요청하는 기능을 제공
getNextPageParam : 다음 페이지를 요청할 때 사용할 페이지 번호를 결정하는 함수initialPageParam : 처음 쿼리를 시작할 때 사용할 페이지 번호const fetchMovie = async page => {
return fetchFromApi(`/movie/now_playing?language=ko-KR&page=${page}`);
};
const useInfiniteScroll = () => {
return useInfiniteQuery({
queryKey: ['now-playing'],
queryFn: ({ pageParam }) => {
return fetchMovie(pageParam);
},
getNextPageParam: last => {
if (last.page < last.total_pages) {
return last.page + 1;
}
return undefined;
},
initialPageParam: 1,
});
};
export default useInfiniteScroll;
const {
data,
isLoading,
error,
fetchNextPage,
hasNextPage,
isFetchNextPage
} = useInfiniteScroll();
return (
<div className="MainPage">
<Header header={'영화'} />
{data?.pages.map((page, i) => (
<MovieList key={i} list={page.results} />
))}
<div className="spinner">
<ClipLoader/>
</div>
</div>
);
fetchNextPage: 다음 페이지 결과 가져오기
hasNextPage : 다음에 가져올 페이지가 있는지에 대한 여부(t/f)
isFetchNextPage : 다음 페이지를 가져오는 동안 true
React 애플리케이션에서 Intersection Observer API를 쉽게 사용할 수 있도록 도와주는 라이브러리
→ 요소가 뷰포트에 들어오거나 나갈 때를 감지할 수 있음
$ npm i react-intersection-observer
뷰포트에 들어왔는지 감지할 요소에 ref 지정
const { ref, inView } = useInView();
return (
<ClipLoader color="#5db996" ref={ref} />
);
const Main = () => {
const {
data,
isLoading,
error,
fetchNextPage,
hasNextPage,
isFetchNextPage
} = useInfiniteScroll();
const { ref, inView } = useInView();
useEffect(() => {
if (inView && hasNextPage && !isFetchNextPage) {
fetchNextPage();
}
}, [inView]);
if (isLoading) {
return <div>Loading</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return (
<div className="MainPage">
<Header header={'영화'} />
{data?.pages.map((page, i) => (
<MovieList key={i} list={page.results} />
))}
<div className="spinner">
<ClipLoader color="#5db996" ref={ref} />
</div>
</div>
);
};
export default Main;
spinner의 로딩바에 react-intersection-observer의 ref를 연결해주면 로딩바 영역이 viewport안에 들어오면서 inView 값이 true가 된다.
다음 데이터를 가져오면 스크롤이 생기면 로딩바 영역이 viewport를 벗어나며 inView 값이 false가 됨
useEffect로 inView값이 변화 될 때 inView값과 다음 페이지가 있을 때와 다음 페이지를 가져오는 값이 모두 true fetchNextPage 함수가 실행되도록한다