React Query useIsFetching 완벽 가이드: 글로벌 로딩 상태 관리의 핵심
웹 애플리케이션을 개발하다 보면 사용자에게 현재 데이터가 로딩 중임을 알리는 과정이 필수적입니다.
일반적으로 개별 컴포넌트에서 isLoading 속성을 사용하여 로딩 스피너를 보여주지만, 수많은 API 요청이 발생하는 대규모 서비스에서는 모든 곳에 로딩 로직을 넣는 것이 비효율적일 수 있습니다.
이때 유용하게 사용할 수 있는 도구가 바로 React Query의 useIsFetching입니다.
본 포스팅에서는 useIsFetching의 동작 원리부터 실무에서 즉시 활용 가능한 글로벌 로딩 인디케이터 구현 방법까지 상세히 살펴보겠습니다.
1. 🔍 useIsFetching이란 무엇인가?
useIsFetching은 현재 애플리케이션에서 백그라운드에서 실행 중인 쿼리의 개수를 반환하는 훅입니다.
쉽게 말해, 현재 Fetching 상태에 있는 쿼리가 하나라도 있다면 그 개수를 숫자로 알려주며, 아무것도 없다면 0을 반환합니다.
주요 특징:
1. 전역 쿼리 상태 감시: 특정 컴포넌트에 종속되지 않고 QueryCache에 있는 모든 쿼리를 감시합니다.
2. 숫자 값 반환: 단순히 boolean이 아니라 현재 로딩 중인 쿼리의 '개수'를 반환하므로 더 세밀한 제어가 가능합니다.
3. 자동 리렌더링: 쿼리 상태가 변경될 때마다 이를 감지하여 컴포넌트를 업데이트합니다.
| 특징 | isLoading (useQuery) | useIsFetching |
|---|---|---|
| 범위 | 단일 쿼리 대상 | 전역 쿼리 대상 |
| 반환 타입 | Boolean | Number (개수) |
| 주요 용도 | 특정 데이터 로딩 표시 | 글로벌 로딩 바, 진행률 표시 |
2. 🚀 글로벌 로딩 인디케이터 구현하기
사용자가 페이지를 이동하거나 여러 데이터를 동시에 불러올 때, 상단에 가느다란 로딩 바(Progress Bar)를 보여주는 것은 매우 훌륭한 UX입니다.
useIsFetching을 사용하면 이를 단 몇 줄의 코드로 구현할 수 있습니다.
function GlobalLoadingIndicator() {
const isFetching = useIsFetching();
return isFetching ? (
<div style={{ position: 'fixed', top: 0, width: '100%', height: '4px', background: 'blue' }} />
) : null;
}
위 코드는 현재 로딩 중인 쿼리가 하나라도 있을 때(isFetching > 0) 화면 최상단에 파란색 막대를 표시합니다.
모든 API 통신이 완료되면 isFetching이 0이 되어 막대가 자연스럽게 사라집니다.
3. 🔍 특정 쿼리만 감시하기: Filtering 활용
모든 쿼리가 아닌, 특정 도메인의 쿼리(예: '/users' 관련)만 로딩 상태를 추적하고 싶을 때가 있습니다.
useIsFetching은 첫 번째 인자로 필터 객체를 전달받아 감시 대상을 제한할 수 있습니다.
주요 필터 옵션:
- queryKey: 특정 키를 포함하는 쿼리만 필터링합니다.
- fetching: 현재 활발하게 데이터를 가져오고 있는 쿼리만 포함합니다.
- stale: 데이터가 상한(stale) 쿼리만 대상으로 합니다.
예를 들어, 'posts'라는 키를 가진 쿼리들의 로딩 상태만 확인하려면 다음과 같이 작성합니다.
이 기능을 활용하면 페이지의 특정 섹션에만 적용되는 로딩 로직을 전역 상태를 거치지 않고도 깔끔하게 구현할 수 있습니다.
4. ⚠️ 성능 최적화와 주의사항
useIsFetching은 강력하지만, 무분별하게 사용하면 성능 저하를 일으킬 수 있습니다.
이 훅은 QueryCache의 상태가 변할 때마다 컴포넌트를 리렌더링시키기 때문입니다.
- 불필요한 리렌더링 방지: 글로벌 로딩 바와 같이 최상단 컴포넌트에서만 사용하고, 하위의 세밀한 컴포넌트에서는 isLoading을 사용하는 것이 좋습니다.
- 메모이제이션 활용: useIsFetching의 결과값을 props로 넘길 때는 React.memo 등을 사용하여 하위 컴포넌트의 불필요한 연산을 막아야 합니다.
- Suspense와의 관계: 만약 React의 Suspense를 사용하고 있다면, useIsFetching 대신 Suspense의 fallback 처리가 우선순위가 될 수 있음을 인지해야 합니다.
5. 더 나은 UX를 위한 선택
useIsFetching은 복잡한 리액트 애플리케이션에서 일관된 사용자 경험을 제공하기 위한 치트키와 같습니다.
개별 로딩 상태를 관리하던 번거로움에서 벗어나, 전역적인 관점에서 데이터 흐름을 시각화할 수 있게 도와주기 때문입니다.
오늘의 핵심 요약:
1. useIsFetching은 전역 쿼리 실행 개수를 반환한다.
2. 글로벌 로딩 바 구현 시 가장 효율적인 도구이다.
3. queryKey 필터링을 통해 특정 그룹의 쿼리만 감시할 수 있다.
4. 리렌더링 비용을 고려하여 최상위 컴포넌트 위주로 배치한다.
이제 여러분의 프로젝트에 useIsFetching을 도입하여 사용자들에게 부드럽고 전문적인 인터페이스를 제공해 보시기 바랍니다.
추가적인 최적화가 필요하다면 useIsMutating과 함께 사용하여 데이터 생성/수정 상태까지 관리해 보는 것을 추천합니다.

댓글 쓰기