컴포넌트를 클릭하면 데이터를 요청하는 UI를 구현하면서 같은 컴포넌트를 클릭해도 첫 번째 클릭과 두 번째 클릭의 체감 속도가 완전히 다르다는 점을 알게 되었다.
- 첫 번째 더블클릭: 로딩 스피너만 돌고, 로딩 스피너 뒤의 화면은 텅 비어 있다가 나중에 데이터 등장
- 같은 항목을 다시 더블클릭: 스피너는 계속 도는데, 스피너 뒤에 이전 데이터가 먼저 보이고 곧 최신 데이터로 갱신됨
React Query의 상태: isLoading vs isFetching
React Query는 로딩 단계를 두 가지로 나눈다.
- isLoading: 캐시에 데이터가 없어 처음 로딩 중이다.
- isFetching: 데이터는 있지만, 최신화를 위해 백그라운드 요청 중이다.
첫 번째 요청에서의 상태
isLoading: true
isFetching: true
화면에 보여줄 데이터가 없고, 지금 처음 데이터를 가져오는 중이다.
따라서 UI는 이렇게 된다.
- 데이터 없음
- 스피너만 보임 → 초기 하드 로딩(hard loading)
두 번째 요청에서는 이렇게 바뀐다
isLoading: false
isFetching: true
화면에 보여줄 캐시 데이터는 있고, 동시에 최신화를 위해 다시 요청 중이다.
- isLoading은 ‘화면이 비는 상황’에서만 true
- isFetching은 ‘백그라운드 요청 여부’일 뿐
UI는 이렇게 변한다.
- 이전 데이터가 즉시 렌더됨
- 뒤에서만 isFetching=true로 새 데이터를 받아 갱신
두 번째 요청이 “훨씬 빠르게 느껴지는” 이유
React Query는 원래 이런 전략을 사용한다. 캐시가 있으면 일단 보여주고(stale), 백그라운드에서 최신화(revalidate)를 수행한다.
즉, HTTP 요청이 빨라진 게 아니라 UI 렌더링 순서가 달라져서 빨라진 것처럼 느껴지는 것이다.
그러면 언제 이 빠름 효과가 사라질까?
gcTime(=cacheTime)이 지나면 캐시가 삭제된다.
- 기본 gcTime: 5분
- 이 시간이 지나면 캐시는 가비지 컬렉션됨
다시 클릭하면? 캐시 없음 → isLoading=true → 느리게 느껴짐
즉, 처음 클릭하는 것처럼 동작이 돌아간다.
staleTime이 0이어도 캐시는 남아 있을까? YES! staleTime=0은 항상 stale 처리하여 refetch한다”는 의미지 캐시를 없앤다는 뜻이 아니다.
참고
const { data, isLoading, isFetching } = useQuery({
queryKey: ['user', userId],
queryFn: fetchUser,
staleTime: 0, // 즉시 stale 처리
gcTime: 5 * 60 * 1000, // 캐시는 5분 보관
});
'Frontend' 카테고리의 다른 글
| 표출할 데이터가 많은 경우 drag 버벅거리는 이슈 (0) | 2025.12.07 |
|---|---|
| key로 컴포넌트 안의 state를 초기화 하기 (0) | 2025.12.07 |
| React-Arborist 트리에서 한글 입력 오류 해결 (3) | 2025.08.25 |
| React-Arborist 트리 UI에서 Input 포커스 문제 해결 (0) | 2025.08.23 |
| eslint 설정해보기 (5) | 2025.07.08 |