간단한 구조로 작성해보았다.
const { ref, inView } = useInView()
const { data, status, fetchNextPage, isFetchingNextPage } = useInfiniteQuery(
'todos',
({ pageParam = 1 }) => fetchTodosList(pageParam),
{
getNextPageParam: (lastPage) => {
return lastPage.nextId !== 200 ? lastPage.nextId : undefined
},
},
)
useEffect(() => {
if (inView) fetchNextPage()
}, [inView, fetchNextPage])
<div>
{data?.pages.map((page, index) => (
<React.Fragment key={index}>
<div
style={{
height: 500,
width: 200,
color: 'white',
background: 'black',
}}
>
{' '}
{page.id} {page.title}
</div>
</React.Fragment>
))}
</div>
{isFetchingNextPage ? <div>로딩중</div> : <div ref={ref}></div>}
기본적으로 todo를 구현해오는 코드가 이렇게 생겼다면,
동작은 3가지로 나뉜다.
// data: query실행시 return data, status: loading | error | success, fetchNextPage : getNextPageParam 의 return값을 argument로 받으며, 쿼리실행, isFetchingNextPage : nextpage패칭중인지가 뜬다.
scroll을 내리다가 ref를 만난다면, inView가 true 로 바뀌며 useEffect가 동작, fetchNextPage가 호출된다.
infinityQuery가 추가로 호출해오면서, data에 추가된 데이터가 배열로 쌓이게된다. 실제로는 data에 page와 pageparam
{pages: Array(5), pageParams: Array(5)}