무한 스크롤 구현
모바일 버전을 베이스로 프로젝트를 만들고 있기 때문에 페이지네이션을 무한 스크롤로 구현하기로 했다.
React Query의 useInfiniteQuery 함수를 사용하여 구현하기 위해 자료를 찾아보는데 아래 블로그에 잘 정리되어 있는 것 같아서 이걸 기반으로 구현해보기로 했다.
[React] react-query useInfiniteQuery로 무한스크롤 구현하기
무한스크롤(Infinite Scroll)? 게시판 글 리스트처럼 많은 데이터를 배열로 받아오는 경우, 그 데이터가 너무 방대해지면 api 요청으로 데이터를 받아오는 시간이 오래걸릴 수 밖에 없게됩니다. 우리
s0ojin.tistory.com
기본적인 개념은 Intersection Observer API를 사용하여 유저가 스크롤을 가장 아래로 내렸을 때를 감지하여 다음 데이터를 불러오는 함수를 실행하는 방식이다.
메인페이지 컴포넌트의 가장 아래에 빈 div를 추가하고 ref를 설정하여 해당 div태그가 감지될 때 다음 데이터를 불러오는 함수를 실행하면 된다.

* 그냥 div태그만 추가하니 감지가 잘 안되서 높이 50px을 추가해줬다.
useInview hook
처음에는 위 블로그에서 처럼 Intersection Observer API hook을 만들어서 사용하려고 했는데, 찾아보니 비슷한 역할을 하는 useInview라는 module을 찾을 수 있었다.
https://www.npmjs.com/package/react-intersection-observer
react-intersection-observer
Monitor if a component is inside the viewport, using IntersectionObserver API. Latest version: 9.5.2, last published: 2 months ago. Start using react-intersection-observer in your project by running `npm i react-intersection-observer`. There are 907 other
www.npmjs.com
해당 모듈에서 useInview hook을 사용하여 ref, inView 를 사용하여 무한 스크롤을 구현할 수 있다.

ref가 view에 들어오면 inView가 true로 바뀌는데, 이 때 useEffect hook이 동작하여 다음 데이터를 불러오는 fetchNextPage 함수를 실행시킨다.
useInfiniteQuery
useInfiniteQuery는 React query에서 특정한 조건이 만족할 때 데이터를 일정한 단위로 불러오는 hook이다. useInfiniteQuery를 사용하면 객체를 반환하는데, 자세한 api 설명은 아래 React query 공식문서를 참고하면 된다.
https://tanstack.com/query/v4/docs/react/reference/useInfiniteQuery
useInfiniteQuery | TanStack Query Docs
const { fetchNextPage,
tanstack.com

useInfiniteQuery hook은 여러 옵션을 설정할 수 있는데, 이번 프로젝트에서는 queryKey, queryFn, getNextPageParam을 옵션으로 지정해줬다.
queryKey는 불러올 데이터를 저장할 key를 지정해주는것으로 events라는 이름으로 저장되도록 설정했다.
queryFn은 다음데이터를 불러올 함수로 다음과 같은 함수를 지정해준다.

12개씩 데이터를 get 할 수 있도록 함수를 작성했고, 에러발생시 임시로 문자열을 return하도록 했다.
getNextPageParam 옵션은 위의 콜백함수를 실행시킬 때 pageParam 인자로 넘겨줄 데이터를 반환하는 함수를 지정하는데, 다음과 같이 작성했다.

12개의 데이터씩 불러올 수 있도록 함수를 작성했고, 1000개의 데이터가 넘어가면 false를 반환하여 데이터를 그만 불러올 수 있도록 했다.
이렇게 작성한 useInfiniteQuery hook은 객체를 반환하는데, 여기서 필요한 프로퍼티를 꺼내서 사용하면 된다.
여기서 중요한것은 data와 fetchNextPage 함수이다.
data는 말 그대로 불러온 데이터를 담고있는데, 특정 조건이 만족하여 추가로 데이터를 불러오면 이 data에 데이터가 추가되어 갱신된다. 옵션으로 준 queryKey로 해당 데이터가 캐싱된다.
** React Query는 데이터를 불러올 때 자동으로 캐싱되기 때문에 다른 곳에서 data가 필요하면 해당 key로 캐싱된 데이터를 불러와 사용하면 된다.
fetchNextPage 함수는 특정한 조건을 만족할 때 실행할 함수이다. useInfiniteQuery hook을 불러올 때 옵션으로 queryFn에 넣어준 함수에 getNextPageParam 인자를 넣고 실행한다.
무한 스크롤 구현

무한 스크롤을 구현할 컴포넌트에서 위와 같이 필요한 작업을 하고,

무한스크롤을 적용할 컴포넌트 아래에 빈 div를 추가해주면 끝이다!
* useInfiniteQuery의 isFetchingNextPage 프로퍼티를 사용하면 데이터를 불러오는 중이면 Loading 컴포넌트를 띄우도록 코드를 작성했다.

Reference
- https://s0ojin.tistory.com/58
- https://www.npmjs.com/package/react-intersection-observer
'토이 프로젝트 > 서울시문화행사' 카테고리의 다른 글
Next.js 프로젝트 - 프로젝트 세팅 (0) | 2023.07.28 |
---|---|
Next.js project - 서울시 문화행사 정보 (0) | 2023.07.22 |
React로 웹페이지만들기 - 서울시 문화행사(6) (0) | 2023.03.13 |
React로 웹페이지만들기 - 서울시 문화행사(5) (0) | 2023.03.11 |
React로 웹페이지 만들기 - 서울시 문화행사(4) (0) | 2023.03.06 |
댓글