무한 스크롤이란 '인스타그램', '유튜브' 앱과 같이 밑으로 스크롤을 내리다가, 마지막에 도달하면 새로운 데이터가 계속해서 추가되는 방식의 페이지 처리 방법을 뜻합니다.
직접 구현하는 방법도 있지만 대표적인 라이브러리인 'react-infinite-scroller' 라이브러리를 이용하면 손 쉽게 구현할 수 있습니다.
https://www.npmjs.com/package/react-infinite-scroller
DOCS를 살펴보면 아래와 같이 구현된다고 나와 있습니다.
<InfiniteScroll
pageStart={0}
loadMore={loadFunc}
hasMore={true || false}
loader={<div className="loader" key={0}>Loading ...</div>}
>
{items} // <-- This is the content you want to load
</InfiniteScroll>
pageStart : 로드할 첫 번째 페이지 번호입니다
loadMore : 사용자가 더 많은 항목을 요청할 때의 콜백입니다.
hasMore : 로드할 항목이 더 있는지 여부입니다
useWindow : 창에 스크롤 리스너를 추가하거나 구성요소의 parentNode
loader : 더 많은 항목이 로드되는 동안 렌더링할 React 구성 요소입니다. 상위 구성 요소에는 고유한 키 속성이 있어야 합니다.
...
로 구성되어 있습니다.
loadMore의 콜백 함수를 만들기 위해서 우리는 graphql의 fetchMore과 updateQuery를 이용할 것입니다.
fetchMore({
variables: { page: Math.ceil(data?.fetchBoardComments.length / 10) + 1 },
updateQuery: (prev, { fetchMoreResult }) => {
if(!fetchMoreResult?.fetchBoardComments)
return { fetchBoardComments: [...prev.fetchBoardComments] }
return {
fetchBoardComments: [...prev.fetchBoardComments, ...fetchMoreResult?.fetchBoardComments]
};
},
});
apollo-client의 useQuery에서 제공하는 fetchMore함수의 내장함수인 updateQuery를 이용해 prev, fetchmoreresult를 인자로 받음, 각각 이전에 받은 data와 추가 데이터를 받아서 배열에 복사를 해서 합쳐준 후 return을 시켜줍니다
위와 같은 방식을 이용해 다음 page에 해당하는 데이터를 불러와 기존 데이터 뒤에 이어지도록 붙여 주어 함수를 작성해 loadMore 요소에 넣어줍니다.
<div style={{height: '500px', overflow:'auto'}}>
<InfiniteScroll
pageStart={0}
loadMore={onloadMore}
hasMore={true}
useWindow={false}
loader={<div className='loader' key={0}>Loading...</div>}>
{data?.fetchBoards.map((el) => (
<div key={el._id}>
<span>
<input type='checkbox' />
</span>
<span style = {{margin: "10px"}}>{el.writer}</span>
<span style = {{margin: "10px"}}>{el.title}</span>
</span>
</div>))}
</InfiniteScroll>
</div>
이후 위 코드처럼 무한스크롤 영역을 div 태그로 감싸준 후 사이즈를 고정시키 하단 끝 부분의 한계를 지정해줍니다. 이후 overflow css기능을 이용해 고정된 사이즈 안에서 스크롤로 내릴 수 있도록 지정해 줍니다.
이 때 useWindow 요소를 false로 설정해 우리가 지정해준 사이즈인 임의값으로 수정할 수 있게 해줘서 구현할 수 있습니다.
