본문 바로가기
카테고리 없음

[React] 무한 스크롤(더보기) 구현하기: useState에서 React Query로의 여정

by demonic_ 2025. 3. 9.
반응형

 

1. 초기접근: useState 를 이용한 구현

검색영역과 뷰 영역을 분리하고 있는 와중에 처음에는 단순히 useState를 사용하여 구현을 시도했습니다:

 

const [searchParams, setSearchParams] = useState({
  searchText: "",
  lastId: DEFAULT_LAST_ID_DESC
});
const [customerList, setCustomerList] = useState([]);
 
 

하지만 이 방식에는 몇 가지 문제가 있었습니다:

 

1. 상태 동기화 문제

  - setState는 비동기적으로 동작하기 때문에, 더보기 클릭 시 이전 상태값을 참조하는 문제 발생

  - API 호출 시점과 상태 업데이트 시점의 불일치

2. 데이터 관리의 복잡성

  - 기존 목록에 새로운 데이터를 추가하는 로직이 복잡해짐

  - 중복 데이터 처리나 에러 상황 대응이 어려움

 

 

2. Jotai를 사용한 시도

다음으로 전역 상태 관리를 위해 Jotai를 시도했습니다:

const searchParamsAtom = atom({
  searchText: "",
  lastId: DEFAULT_LAST_ID_DESC
});

 

 

하지만 이 역시 useState와 비슷한 문제에 직면했습니다:

1. 상태 업데이트 타이밍

  - useState와 비슷한 동작 방식으로 인해 상태 업데이트 타이밍 이슈 지속

  - 더보기 시 이전 lastId를 참조하는 문제 해결되지 않음

2. 데이터 페칭 로직과의 통합

  - 상태 관리와 데이터 페칭 로직이 여전히 분리되어 있어 복잡성 존재

 

 

3. 최종 해결책: React Query의 useInfiniteQuery

결국 React Query의 useInfiniteQuery를 사용하여 문제를 해결했습니다:

const {
  data,
  fetchNextPage,
  hasNextPage,
  refetch,
  isFetchingNextPage
} = useInfiniteQuery({
  queryKey: [QUERY_KEY, searchParams],
  queryFn: ({ pageParam = DEFAULT_LAST_ID_DESC }) => 
    fetchGet("/api/v1/admin/customer/manage", {
      searchText: searchParams.searchText,
      lastId: pageParam
    }),
  getNextPageParam: (lastPage) => {
    if (lastPage.data.length !== searchParams.size) {
      return undefined;
    }
    return lastPage.lastId;
  }
});

 

 

1. 자동화된 상태 관리

  - 페이지네이션 상태를 자동으로 관리

  - 캐시 처리가 내장되어 있어 성능 최적화 용이

2. 직관적인 API

  - fetchNextPage, hasNextPage 등 필요한 기능이 이미 구현되어 있음

  - 로딩 상태 관리가 간편함

3. 데이터 무결성

  - 캐시와 실제 데이터의 동기화가 자동으로 처리됨

  - 중복 요청 방지 기능 내장

 

 

주요기능 사용:

더보기: 다음 데이터를 불러오는데 추가 코딩 없이 함수 한번으로 바로 호출되는 점이 좋았습니다

const handleAddSearch = () => {
  if (!hasNextPage) {
    toast.warn("더 이상 데이터가 없습니다.");
    return;
  }
  fetchNextPage();
};

 

 

검색초기화: refetch 를 쓰면 첫페이지로 돌아가는게 아니라 지금까지 불러왔던것을 순서대로 모두 불러오고 있었습니다. 제가원한건 첫페이지로 이동하는 것이기 떄문이 catch 를 제거함으로써 갱신되도록 개발했습니다.

const handleSearch = async () => {
  await queryClient.resetQueries([QUERY_KEY, searchParams]);
  refetch();
};

 

 

 

4. 배운 점

상태 관리 도구 선택의 중요성
  - 단순 상태 관리 vs 데이터 페칭 관리
  - 각 도구의 특성과 적절한 사용 상황

React Query의 강점
  - 데이터 페칭에 특화된 기능
  - 캐시 관리의 편리함
  - 무한 스크롤/더보기 구현의 용이성

성능 최적화
- 불필요한 리렌더링 방지
- 효율적인 데이터 캐싱
- 사용자 경험 개선



결론

복잡한 데이터 페칭과 상태 관리가 필요한 경우, React Query와 같은 전문화된 도구를 사용하는 것이 더 효율적입니다. 특히 무한 스크롤이나 더보기 기능 구현 시 useInfiniteQuery가 개발편리한 기능을 많이 제공합니다.

 

반응형