객체를 복사할 때마다 깊은 복사를 따로 해주기는 번거롭고 느릴 수 있습니다.
그래서, 관련 작업을 도와주는 라이브러리가 많이 나와있습니다.
가장 많이 사용되는 기능 모음 라이브러리 중 하나인 lodash를 살펴보겠습니다.
lodash에서 제공하는 _.cloneDeep(value)
을 사용하면 손쉽게 깊은 복사를 할 수 있습니다.
리스트를 스크롤 하다가 종단점에 도달하면 새로운 데이터가 계속해서 추가되는 방식의 페이지 처리 방법을 무한스크롤 방식이라고 합니다.
아래의 라이브러리는 가장 많이 사용되는 react infinite scroller library 중 하나인 react-infinite-scroller 라이브러리입니다.
react-infinite-scroller npm 링크
❗️ 설치 후 실행 시 타입스크립트 오류가 발생하는 경우, 아래의 코드를 복사하여 타입을 설치해 주세요.
yarn add -D @types/react-infinite-scroller
Container.tsx
const onLoadMore = () => {
if(!data) return;
fetchMore({
variables: { page: Math.ceil(data?.fetchBoardComments.length / 10) + 1 },
// 다음 페이지 불러오기
// 현재 1 ~ 30까지 댓글이 있다면 '(30 / 10) + 1 = 4' 이므로 4페이지 불러오기
updateQuery: (prev(기존 데이터), fetchMoreResult) => {
if(!fetchMoreResult?.fetchBoardComments)
return { fetchBoardsCmoments: [...prev.fetchBoardComments] };
// 추가 댓글이 없다면 이전 댓글들만 다시 리턴
return {
fetchBoardComments: [...prev.fetchBoardComments, ...fetchMoreResult?.fetchBoardComments],
} // 이전 댓글들과 추가 댓글들을 합쳐서 리턴
}
})
}
// fetchBoardComments => 전체 댓글들
// prev.fetchBoardComments => 이전 댓글들 (1 ~ 30)
// fetchMoreResult?.fetchBoardComments => 추가 댓글들 (31 ~ 40)
Presenter.tsx
<InifniteScroll
paegStart={0}
loadMore={onLoadMore}
hasMore={true || false}
loader={<div className="loader" key={0}>Loading...</div>}
>
{data?.fetchBoards.map((el) => (
<div key={el.id}>
<span>{el.writer}</span>
<span>{el.title}</span>
<span>{el.contents}</span>
</div>
))}
</InfiniteScroll>
무한스크롤을 적용하고 싶은 영역을 InfiniteScroll
태그를 사용하여 감싸줍니다.
그리고, 스크롤 영역이 하단 끝에 닿았을 때 실행되어야 할 기능을 함수로 만들어 loadMore
요소에 지정해 줍니다.
Apollo-Client의 useQuery에서 제공하는 fetchMore
함수를 함께 사용하면 다음 page에 해당하는 데이터를 불러와 기존 데이터 위에 이어지도록 붙여줄 수 있습니다.