피드로 돌아가기
useInfiniteQuery로 무한스크롤 구현하기
올리브영 테크블로그올리브영 테크블로그
Frontend

useInfiniteQuery로 무한스크롤 구현하기

올리브영이 useInfiniteQuery와 react-intersection-observer로 검색 결과 페이지 무한스크롤 구현 및 sessionStorage 활용으로 뒤로가기 시 스크롤 위치·상품목록 복원

2023년 10월 4일12intermediate

Context

올리브영의 검색 결과 페이지가 신규 아키텍처로 전환되며 무한스크롤 기능이 필요했다. 상품 상세페이지(구 몰)와 검색 결과 페이지(신규 아키텍처)가 분리된 프로젝트로 운영되어 브라우저 자체 스크롤 유지 기능으로는 해결이 불가능했다. 특히 2페이지 이상의 상품을 클릭한 후 뒤로가기 시 해당 페이지까지 데이터를 모두 로드하지 않아 단순 스크롤 위치 이동만으로는 UX를 확보할 수 없었다.

Technical Solution

  • useInfiniteQuery로 무한스크롤 구현: react-query의 useInfiniteQuery 훅으로 pageParam을 관리하고 getNextPageParam에서 lastPage의 데이터 개수와 rowsPerPage 비교로 마지막 페이지 판단(레거시 API에 pagination 정보 부재로 인한 우회)
  • react-intersection-observer의 useInView로 뷰포트 감지: 마지막 상품 카드가 뷰포트에 진입하는 시점을 감지하여 fetchNextPage 자동 호출
  • sessionStorage로 상품 인덱스 및 스크롤 위치 저장: 상품 상세페이지 이동 시 클릭한 상품의 인덱스값과 스크롤 Y값을 sessionStorage에 저장
  • queryClient.prefetchInfiniteQuery로 조건부 데이터 사전 로드: 검색 결과 페이지 재진입 시 저장된 인덱스값까지만 데이터를 미리 로드하여 스크롤 위치 도달 시 필요한 상품 데이터가 이미 메모리에 존재하도록 구성
  • 검색입력창 첫 진입 시 sessionStorage 초기화: 새로운 검색어로 검색 결과 페이지 진입 시 이전 검색의 sessionStorage 값 영향을 방지하기 위해 검색입력창 페이지 첫 로드 시 값 제거

Key Takeaway

크로스 프로젝트 아키텍처 환경에서는 sessionStorage와 react-query의 prefetchInfiniteQuery를 조합하여 상태 복원이 필요한 페이지의 정확한 스냅샷을 저장·복구할 수 있다. 마지막 페이지 판단 로직을 API 응답 데이터 자체에서 추론하는 방식은 레거시 API 대응 시 유효한 패턴이다.


react-query를 사용하는 무한스크롤 구현 환경에서 sessionStorage에 마지막 조회 인덱스와 스크롤 Y값을 저장한 후, 페이지 재진입 시 prefetchInfiniteQuery로 해당 인덱스까지만 사전 로드하면 뒤로가기 시에도 이전 상태를 정확히 복원할 수 있다. 이 방식은 프로젝트 분리 구조에서 브라우저 자체 스크롤 복구 기능을 우회해야 할 때 특히 유용하다.

원문 읽기