React Query(리액트 쿼리) - Fresh, Stale, Inactive, Fetching
iskkiri • 2024년 09월 21일
React Query에서 사용되는 네 가지 주요 상태인 Fresh, Stale, Inactive, Fetching에 대해 알아보겠습니다.
코드와 예제 결과는 Codesandbox에서 직접 확인할 수 있습니다.
Fresh 상태
Fresh 상태는 데이터를 다시 서버에 요청할 필요가 없는, 즉 최신 상태를 의미합니다. 데이터를 서버에서 받아온 후 지정된 staleTime 내에 있는 데이터는 fresh 상태로 간주됩니다.
- staleTime은 데이터를 신선하다고 간주하는 시간입니다. 기본값은 0ms로, 즉시 stale 상태가 되지만, 설정을 통해 staleTime을 늘릴 수 있습니다.
- fresh 상태에서는 데이터가 신선하므로, 사용자가 다시 요청할 때 캐싱된 데이터가 사용되며 서버에 재요청하지 않습니다.
예시: staleTime: 5 * 60 * 1000 (5분)으로 설정된 경우, 데이터를 가져온 후 5분 동안은 fresh 상태가 유지됩니다.
Stale 상태
Stale 상태는 데이터가 신선하지 않다는 상태를 의미하며, 새로운 데이터가 필요할 가능성이 있는 상태입니다. staleTime이 지나면 데이터는 stale 상태로 전환되며, 이때 React Query는 데이터가 사용되거나 특정 이벤트가 발생할 때(예: 컴포넌트가 마운트될 때) 백그라운드에서 리패칭(refetching)을 진행합니다.
- Stale 상태에서는 캐시된 데이터가 먼저 사용되지만, 백그라운드에서 새로운 데이터를 페칭하여 최신 상태로 갱신합니다.
- 주로 refetchOnWindowFocus, refetchOnReconnect와 같은 옵션과 함께 작동하여, 사용자가 다시 페이지를 방문하거나 네트워크가 재연결될 때 데이터를 자동으로 갱신합니다.
Inactive 상태
Inactive 상태는 쿼리가 더 이상 활성화되지 않았을 때 발생합니다. 주로 해당 쿼리를 사용하는 컴포넌트가 언마운트되었을 때 발생하며, 이 상태에서 데이터는 캐시에 남아 있지만 사용되지 않습니다.
- Inactive 상태에서는 해당 쿼리가 사용되지 않기 때문에, 자동으로 리패칭되지 않으며, 필요할 때까지 캐시에 보존됩니다.
- gcTime: Inactive 상태가 지속될 수 있는 시간을 정의하며, 이 시간이 지나면 데이터는 캐시에서 삭제됩니다. 기본값은 5분입니다.
Fetching 상태
Fetching 상태는 데이터를 서버에서 가져오는 중인 상태를 의미합니다. 즉, 새로운 데이터를 요청하고 있는 동안 발생하며, 사용자는 이때 isLoading 또는 isFetching 같은 상태를 활용해 로딩 상태를 처리할 수 있습니다.
- Fetching 상태는 사용자가 새로 데이터를 요청하거나, 백그라운드 리패칭이 발생할 때 표시됩니다.
- isLoading은 쿼리가 처음 페칭될 때 사용되며, 이후에는 isFetching이 로딩 중임을 나타냅니다.
예제를 통해 이해하기
위에서 설명한 fresh, stale, inactive, fetching의 이해를 돕기위한 예제 코드와 예제 실행 페이지를 바탕으로 설명하겠습니다.
- 게시글 목록 페이지에서 1번 게시글을 클릭하여 상세 페이지로 이동합니다.
- 게시글 목록의 query key인 ["POSTS"]는 상세 페이지에서 사용되지 않기 때문에 inactive 상태로 변경된 것을 확인할 수 있습니다.
- 1번 게시글의 query key인 ["POSTS", {"id": 1}]는 현재 데이터 요청 중이기 때문에 fetching 상태로 변경된 것을 확인할 수 있습니다.
2. 뒤로가기 후 1번 게시글로 재이동 시
- 캐싱된 데이터로 인해 상세 페이지가 바로 보이는 것을 확인할 수 있습니다. 그러나 background refetching이 발생하여 ["POSTS", {"id": 1}]는 fetching 상태로 전환됩니다.
3. staleTime 설정 후 fresh 상태 확인하기
예제 코드의 useQuery를 아래와 같이 변경합니다.
const { data: post, isLoading } = useQuery({
queryKey: ["POSTS", { id }],
queryFn: async () => {
await new Promise((resolve) => setTimeout(resolve, 10000));
return getPostDetailApi(id);
},
staleTime: 60 * 1000,
});
- staleTime을 1분으로 설정한 이후에 게시글 목록 페이지에서 새로고침 후 다시 상세 페이지로 이동합니다.
- 그러면 이번에는 ["POSTS", {"id": 1}]이 fresh 상태로 전환됩니다.
- 뒤로가기 후 다시 상세페이지로 진입하면 staleTime을 설정하기 이전과는 다르게 fetching상태로 전환되지 않는 것을 확인할 수 있습니다.
- 이는 fresh한 상태일 때는 데이터를 신선하다고 간주하여, 서버에 재요청하지 않기 때문입니다.
React Query를 처음 접하는 경우, 특히 캐싱과 stale 상태에 대한 개념이 혼란스러울 수 있습니다. 이를 다시 한번 정리해보면 다음과 같습니다.
- Caching은 이전에 요청했던 데이터를 메모리에 저장해두는 것을 의미하며, gcTime 옵션을 이용해 시간을 설정할 수 있습니다. 참고로 gcTime이 지나면 가비지 컬렉터(Garbage Collector)에 의해 메모리에서 제거됩니다.
- Stale 상태는 캐시된 데이터가 더 이상 신선하지 않고, 재요청이 필요할 가능성이 있는 상태를 의미합니다. React Query에서 데이터는 처음 페칭한 후 일정 기간 동안 fresh 상태를 유지하며, 이 기간이 staleTime으로 정의됩니다. staleTime의 기본값은 0ms입니다.
gcTime과 staleTime의 기본값을 변경하지 않고 사용하더라도, 일반적인 프로젝트 진행에는 문제가 없습니다. 그러나 최적화를 시도하면서 이러한 설정에 대한 정확한 이해 없이 임의로 값을 조정할 경우, 데이터 업데이트가 되지 않는 등 예기치 않은 문제가 발생할 수 있습니다.
따라서, 캐싱과 stale 상태의 개념을 충분히 이해한 후 설정을 변경하는 것이 바람직합니다.