본문 바로가기
토이 프로젝트/서울시문화행사

프로젝트 - 무한 스크롤 구현

by 강물둘기 2023. 8. 20.

무한 스크롤 구현

모바일 버전을 베이스로 프로젝트를 만들고 있기 때문에 페이지네이션을 무한 스크롤로 구현하기로 했다. 

React Query의 useInfiniteQuery 함수를 사용하여 구현하기 위해 자료를 찾아보는데 아래 블로그에 잘 정리되어 있는 것 같아서 이걸 기반으로 구현해보기로 했다.

 

https://s0ojin.tistory.com/58

 

[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

- https://velog.io/@hdpark/React-Query%EC%99%80-%ED%95%A8%EA%BB%98%ED%95%98%EB%8A%94-Next.js-%EB%AC%B4%ED%95%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4

 

 

 

 

댓글