
stale-while-revalidate는 확장 Cache-Control 디렉티브이다. (Cache-Control은 HTTP 요청과 응답에서 사용되는 헤더의 일종으로, 캐싱 메커니즘을 위해 사용된다.)
캐시된 컨텐츠를 즉시 로드하는 즉시성과 업데이트 된 캐시 컨텐츠가 향후에 사용되도록 하는 최신성을 보장하는 데 도움을 준다. stale-while-revalidate는 비동기적으로 컨텐츠를 재검증하는 동안 클라이언트가 stale한(=최신이 아닌) 응답을 받을 것임을 나타낸다.
Cache-Control: max-age=1, stale-while-revalidate=59
React Query는 이러한 stale-while-revalidate 전략을 채택한 비동기 상태 관리자이다. 즉, React Query는 데이터를 캐싱하고 요청 시 데이터가 stale하더라도 데이터를 반환한다.
기존


수정 후





invalidateQueries 메서드 사용

App.tsx에서 QueryClient를 이용하여 전역 에러 처리
API 요청은 문제 없이 동작하는데 invalidateQueries가 동작하지 않는 문제가 있었다. 코드는 아래와 같았다.

응답으로 받아온 data에 id가 제대로 들어오지 않는 건가? 라는 생각에 onSuccess 콜백 함수를 async/await로 수정해보았다. 하지만 문제가 해결되지 않았다.
Query Key가 잘못된 게 아니라면 queryClient가 문젠가 싶어서 다른 사람들의 코드와 공식 문서 예시를 찾아보았다. 찾아보니 new QueryClient()가 아니라 useQueryClient()를 사용해야 함을 발견했다.

React Query는 동일한 QueryClientProvider에 있는 경우 동일한 데이터를 가져오고, 동시에 발생하는 요청의 중복을 제거하므로 위의 시나리오에서는 두 컴포넌트가 동일한 데이터를 요청하더라도 네트워크 요청은 하나만 있습니다.
[번역] #10: 리액트 쿼리는 상태 관리자다
queryClient에 대해 잘 알지 못해서 원인을 찾는 데에 시간이 걸렸다. 동일한 queryClient가 아니었기 때문에 invalidate할 해당 쿼리가 존재하지 않아서 생긴 문제인 것 같다. 좀 더 알아봐야겠다..!
App.tsx에서 아래와 같이 queryClient에서 QueryCache를 만들어 OnError 옵션에 대해 콜백 함수를 작성했다. 그런데 몇 몇 API 요청 시 에러가 발생해도 toast가 보이지 않는 문제가 있었다.

모든 API 요청에서 발생한 문제가 아니라 로그인, todo 수정&삭제에서 발생한 문제였다. 코드를 확인해보니 해당 동작의 커스텀 훅을 사용할 때 다른 옵션을 주었기 때문에 옵션이 덮어씌워져서 동작하지 않는 게 아닐까?라고 생각했다.

그래서 옵션을 지우고 다시 확인해보았으나 문제는 해결되지 않았다. 그래서 처음에 전역 에러 처리를 할 때 참고했던 TkDodo의 글에서 'overwrite'를 검색해서 아래와 같은 댓글을 발견했다.

그런데 전역 에러 처리를 하려면 QueryCache나 MutationCache를 사용하라고 적혀있는 것을 보고 MutationCache를 작성하지 않은 게 문제였음을 깨달았다. 그리고 코드를 아래와 같이 수정했고, 문제 없이 잘 동작하는 것을 확인했다!

지난 번에 개인 토이 프로젝트를 할 때에도 React Query를 사용해보려고 했으나, 급한 마음으로 슥 훑어보고는 '어렵다.. 다음에 해 봐야지' 하고 생각했었다. 그런데 어려워도 일단 써봐야 어떻게 하는 건지 조금이라도 감이 오고 결국 사용할 수 있게 되는 것 같다.
공식문서와 여러 포스팅을 읽고 React Query를 사용해보면서 그동안 API 요청에 대해 꼼꼼히 모든 경우를 처리한 적이 없음을 깨달았다. 그리고 관련 코드를 작성할 때 필요한 부분이라는 이유로 코드 품질을 떨어뜨리고 있지는 않았는지 반성하게 되었다. 부족한 나를 도와줄 수 있는 알맞는 도구를 선택하는 것도 중요하겠다는 생각을 했다.
내가 느낀 React Query의 장점은 서버 데이터 관리 로직을 React Query에서 처리함으로써 코드가 간결해지고 서버 데이터를 관리하는 게 편리해졌다는 것이다. 그래서 서버에서 데이터를 가져오는 작업이 많은 앱일 경우 React Query를 사용하는 게 훨씬 좋을 듯하다. React Query에 대한 글을 읽으면서 SWR이 같이 언급되는 경우가 종종 있었는데 둘의 차이점은 무엇인지도 한 번 알아봐야겠다.
참고한 글