Projects

[react-query] observer API와 react-query로 무한스크롤 구현하기

2023. 8. 31. 14:50
목차
  1. useInfiniteQuery 사용하기
  2. 스크롤감지 (observer API)
  3. Ref

모모 프로젝트에서 구현한 무한스크롤에 대해서 포스팅 해보겠습니다.

저는 지난번 솔로 프로젝트에서 라이브러리를 이용해서 무한스크롤을 구현해본 경험이 있는데요

이번에는 내장된 API인 observer API와 react-query의 useInfiniteQuery 훅으로 무한스크롤을 구현해 보았습니다.

 

무한 스크롤의 작동원리는 두 단계로 진행이 됩니다.

1. 스크롤이 뷰포트 바닥에 닿았는지 감지

2. 필요한 데이터 요청

 

useInfiniteQuery 사용하기

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isLoading,
    isError,
  }: UseInfiniteQueryResult<CardData[], unknown> = useInfiniteQuery(
    ['filteredList', keyword, selectedCategoryId, selectedLocationId],
    ({ pageParam = 1 }) => {
      // 생략
      return getList(urlPath, searchData, categoryId, locationId, pageParam);
    },
    {
      getNextPageParam: (lastPage, allPages) => {
        const nextPage = allPages.length + 1;
        return lastPage.length === 0 ? undefined : nextPage;
      },
    },
  );

useInfiniteQuery훅 실행으로 게시물 데이터 요청이 완료가 되면

getNextPageParam 콜백함수를 실행합니다.

이 함수는 두 가지 인자 (lastPage, allPages)를 전달받아서

return 된 값에 따라 요청 파라미터로 전달이 됩니다.

따라서, 게시물 데이터의 첫 페이지는 1이었으니 2, 3, 4 순으로 증가해야하며

마지막 페이지의 게시물 데이터를 만나게되면 undefined 를 return 해주어 마지막 페이지가 없음을 전달해주어야합니다.

 

lastPage, allPages의 형태는 아래와 같습니다.

console.log(lastPage, allPages)

pagePram = 1
pageParam = 5
pageParam = 7 (마지막 페이지)

데이터를 살펴보면 불러온 데이터의 마지막 페이지가 lastPage로

모든 페이지들이 각 요소로들어간 배열인 allPages로 들어가는걸 볼 수 있습니다.

 

따라서, allPages의 length보다 1큰 값이 nextPage가되고

lastPage의 length가 0이라면 데이터가 더이상 존재하지 않음으로 undefined를 return 하는 로직을 작성하였습니다.

 

스크롤감지 (observer API)

getNextPageParam 콜백함수로 useInfiniteQuery 리턴값인 hasNextPage가 다음 페이지가 있음을 알려주고

fetchNextPage로 다음 페이지를 fetch 합니다.

  const scrollTargetRef = useRef(null);

  useEffect(() => {
    const handleScroll: IntersectionObserverCallback = (entries) => {
      const target = entries[0];
      if (target.isIntersecting && hasNextPage) {
        fetchNextPage();
      }
    };
    const observer = new IntersectionObserver(handleScroll, { threshold: 0.1 });
    const target = scrollTargetRef.current;

    if (target) {
      observer.observe(target);
    }
    return () => {
      if (target) {
        observer.unobserve(target);
      }
    };
  }, [hasNextPage]);
  
    return (
    <Wrapper>
	  // 생략
      <div ref={scrollTargetRef}></div>
    </Wrapper>
  );

useRef로 가장 바닥에 있는 요소를 target으로 설정하여

target이 화면영역과 교차되는 순간 target.isIntersecting 이 true가 되면서

다음 페이지가 있으면(hasNextPage === true) fetchNextPage()를 실행합니다.

 

Ref

https://tanstack.com/query/v4/docs/react/reference/useInfiniteQuery

 

useInfiniteQuery | TanStack Query Docs

const { fetchNextPage,

tanstack.com

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

 

Intersection Observer API - Web APIs | MDN

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.

developer.mozilla.org

https://velog.io/@elrion018/%EC%8B%A4%EB%AC%B4%EC%97%90%EC%84%9C-%EB%8A%90%EB%82%80-%EC%A0%90%EC%9D%84-%EA%B3%81%EB%93%A4%EC%9D%B8-Intersection-Observer-API-%EC%A0%95%EB%A6%AC

 

실무에서 느낀 점을 곁들인 Intersection Observer API 정리

실무에서 Intersection Observer API를 사용해보고 느낀 생각정리

velog.io

 

'Projects' 카테고리의 다른 글

[모모] 라이트하우스 성능 개선기  (0) 2023.10.25
[모모] 리액트에서 파일 업로드하기(사용자 프로필 사진 바꾸기)  (0) 2023.09.06
[ESLint, Prettier, Git Hook, Husky] 팀원들과 코드 스타일을 맞추기 위해 설정하면 좋은 툴  (0) 2023.08.27
[모모] React-Query의 캐싱기능으로 api요청을 줄여보자  (6) 2023.08.10
  1. useInfiniteQuery 사용하기
  2. 스크롤감지 (observer API)
  3. Ref
'Projects' 카테고리의 다른 글
  • [모모] 라이트하우스 성능 개선기
  • [모모] 리액트에서 파일 업로드하기(사용자 프로필 사진 바꾸기)
  • [ESLint, Prettier, Git Hook, Husky] 팀원들과 코드 스타일을 맞추기 위해 설정하면 좋은 툴
  • [모모] React-Query의 캐싱기능으로 api요청을 줄여보자
Summer.dev
Summer.dev
프론트엔드 개발자 Summer 입니다! 피드백은 언제나 환영입니다.
Summer.dev
꾸준함이 무기
Summer.dev
전체
오늘
어제
  • 분류 전체보기
    • Projects
      • Next.js board-project
      • MOMO
    • 원티드
    • 우테코 프리코스
    • JavaScript
    • React
    • TypeScript
    • Node.js
    • Algorithm
      • 코플릿
      • 개념정리
    • 네트워크
    • 오류해결
    • 회고
    • 기술면접준비
    • git,github
    • 소소하게 궁금한것
    • Next.js Beta Docs 번역
    • 디자인패턴
    • 트러블슈팅
    • 번역

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 알고리즘
  • 메모이제이션

최근 댓글

최근 글

hELLO · Designed By 정상우.
Summer.dev
[react-query] observer API와 react-query로 무한스크롤 구현하기
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.