1. 과정

1. 프로필 데이터 불러오기

export const useGetProfile = () =>
  useSuspenseQuery(Keys.getProfile(), getProfile,
    staleTime: Infinity,
  });

export const useGetProfileById = (userId: number) =>
  useSuspenseQuery(Keys.getProfileById(userId), 
    staleTime: Infinity,
  });

프로필 데이터는, 본인이 직접 바꾸지 않는 한 데이터가 바뀌지 않는다. 그래서, 프로필 수정을 했을 경우에만 데이터를 서버에서 다시 받아오면 된다.

  1. staleTime을 Infitnity로 설정했다.
  2. 즉, 서버로부터 전달받은 데이터는 영원히 fresh상태이며, 캐싱된 데이터라 사라지지 않는 한 데이터를 refetch하지 않는다.

<aside> ❓ cache? stale?

정리하자면, staleTime은 데이터를 refetch하기까지의 시간이고, cacheTime은 캐싱된 데이터가 보존되기 까지의 시간이다. 즉, cacheTime이 만료되지 않더라도 staleTime이 지났다면 데이터를 재요청한다.

Screenshot 2024-01-12 at 2.33.25 PM.png

위 그림처럼 데이터를 요청하고 나면 데이터는 fresh상태가 된다. 그리고, staleTime이 지나면 stale상태가 된다.

2. invalidateQueries를 통해 캐시를 초기화

export const usePatchProfile = () => {
  const queryClient = useQueryClient();
  const { back } = useAppRouter();
  return useMutation(patchProfile, {
    onSuccess: () => {
      queryClient.invalidateQueries(Keys.getProfile());
      back();
    },
  });
};

queryClient.invalidateQueries를 사용하여 캐싱된 데이터를 초기화하여, 데이터를 refetch한다.

<aside> ❓ 그렇다면, Stale과 Cache 두 개가 있을 필요가 있을까?

stale없이 cache만으로 데이터를 관리할 경우, 데이터를 받아오는 ‘로딩’상태가 생기게 된다.

새로운 데이터를 받아올 때를 가정해보자.

  1. stale과 cache가 모두 존재한다면, 데이터를 받아오는 동안 staleTime은 지났지만, cacheTime은 지나지 않은 stale캐싱 값을 보여주면 된다.
  2. cache만 존재한다면, 데이터를 받아오는 동안 보여줄 데이터가 없다. 로딩 화면을 보여줘야한다. 왜냐하면 cacheTime이 지난 데이터는 폐기했기 때문이다.

이러한 이유로 react-query는 stale과 cache 두 개로 나누어 캐싱 데이터를 관리한다.

</aside>

2. 결론

무조건 staleTime은 1분. 이런 식으로 정해놓고 하는 것이 아니라, 데이터의 성격에 따라 다시 불러올 것인지, 상황에 따라서 데이터를 불러올 것인지 고려를 하면서 개발을 하면 더 효율적인 데이터 요청을 할 수 있을 것이라 생각했다.