React

React 무한스크롤 react-infinite-scroll-component와 React Query (useInfiniteQuery)

와이다이어리 2025. 6. 9. 01:50
반응형

1. 무한스크롤이란?

  • 사용자 경험을 부드럽게 해주는 데이터 로딩 UI 패턴
  • 스크롤이 끝에 도달하면 자동으로 다음 페이지 데이터를 불러오는 방식
  • 페이징보다 직관적, 모바일 환경에 최적화됨

2. 대표 라이브러리 소개

2-1. react-infinite-scroll-component

  • 매우 간단하고 직관적인 무한스크롤 라이브러리
  • 데이터 로딩과 UI 렌더링 모두를 한 컴포넌트에서 처리 가능
  • 최소한의 설정으로 빠르게 구현 가능

2-2. React Query의 useInfiniteQuery

  • 서버 상태 관리, 데이터 캐싱, 리패칭 등 강력한 기능 제공
  • useInfiniteQuery 훅으로 무한스크롤 페이징 로직을 쉽게 구현
  • 스크롤 이벤트 감지는 직접 구현해야 하며, UI와 데이터 로딩을 분리하는 스타일

3. react-infinite-scroll-component 상세 사용법

설치

npm install react-infinite-scroll-component

 

기본 사용 예시

import InfiniteScroll from 'react-infinite-scroll-component';

const MyComponent = () => {
  const [items, setItems] = useState(initialItems);
  const [hasMore, setHasMore] = useState(true);

  const fetchMoreData = () => {
    // 서버에서 데이터 받아오기 (비동기)
    fetchNextPageData().then(newItems => {
      if (newItems.length === 0) {
        setHasMore(false);
      } else {
        setItems([...items, ...newItems]);
      }
    });
  };

  return (
    <InfiniteScroll
      dataLength={items.length}
      next={fetchMoreData}
      hasMore={hasMore}
      loader={<h4>Loading...</h4>}
      endMessage={<p>더 이상 불러올 게시글이 없습니다.</p>}
    >
      {items.map(item => (
        <div key={item.id}>{item.title}</div>
      ))}
    </InfiniteScroll>
  );
};

 

특징 및 장점

  • 스크롤 감지 및 데이터 요청 로직을 단순화
  • 로딩 중, 끝 메시지 표시 UI 내장
  • 간단한 API로 초보자도 쉽게 사용 가능

단점

  • 데이터 캐싱, 자동 리패칭 등 고급 기능 부족
  • 스크롤 위치 등 세밀한 제어 어려움
  • 데이터 상태를 직접 관리해야 함

4. React Query useInfiniteQuery 활용법

설치

npm install @tanstack/react-query

 

기본 사용 예시

import { useInfiniteQuery } from '@tanstack/react-query';

const fetchPosts = async ({ pageParam = 1 }) => {
  const res = await fetch(`/api/posts?page=${pageParam}`);
  return res.json();
};

const MyComponent = () => {
  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery(
    ['posts'],
    fetchPosts,
    {
      getNextPageParam: lastPage => lastPage.nextPage ?? false,
    }
  );

  useEffect(() => {
    const onScroll = () => {
      if (
        window.innerHeight + window.scrollY >= document.body.offsetHeight - 300 &&
        hasNextPage &&
        !isFetchingNextPage
      ) {
        fetchNextPage();
      }
    };
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, [fetchNextPage, hasNextPage, isFetchingNextPage]);

  return (
    <div>
      {data?.pages.map((page, idx) =>
        page.items.map(item => <div key={item.id}>{item.title}</div>)
      )}
      {isFetchingNextPage && <h4>Loading more...</h4>}
      {!hasNextPage && <p>모든 게시글을 불러왔습니다.</p>}
    </div>
  );
};

 

특징 및 장점

  • 서버 상태 자동 캐싱, 상태 관리
  • 중복 요청 방지, 에러 재시도 기능 내장
  • 페이지네이션 로직 명확히 분리
  • 데이터 업데이트가 쉬움 (리패칭, 뮤테이션 등)

단점

  • 스크롤 이벤트 직접 구현 필요
  • 러닝 커브 존재, Hooks 이해 필요
  • 간단한 프로젝트에는 과할 수 있음

5. 결론 및 추천

  • 초보자, 빠르게 구현하고 싶다면 → react-infinite-scroll-component
  • 서버 상태 관리까지 포함한 고급 기능 필요하면 → React Query의 useInfiniteQuery
  • 프로젝트 규모, 팀 숙련도에 따라 선택

 

반응형