tanstack-query의 useInfinityQuery를 통해 무한 스크롤을 구현하였는데, 데이터를 추가/ 삭제/ 수정해도 이전에 받아온 데이터가 유지되는 현상이 발생했다. 처음에는 당연히 queryClient.invalidateQueries를 통해서 간단히 해결될 문제라고 생각했는데, 안된다. useInfinityQuery의 refetch를 사용하면 될 줄 알았는데, 안된다. 콘솔을 찍어보니 냉장고 id가 undefined로 들어가고 있었다. URL params에서 useState로 변경하던 중에 이런 에러가 발생했던 것 같다. 하지만 냉장고 id를 제대로 보내줘도 결과는 똑같았다. 왜 안되는건지 이해가 안되는 중에, 일단 마감기간은 다가오니 캐시데이터를 삭제하는 방법을 사용하기로 했다. 하지만 queryClient에서 cacheTime을 넣자마자 타입에러가 생겼다. 분명 나는 2개월전에 쓴거같은데 그새 사라졌다. 삽질을 조금 시도하다가 일단 시간이 급해서 넘어갔고 다음날에서야 gcTime으로 명칭이 바뀐걸 알았다. onError deprecated 관련해서 찾아볼때 좀 더 알아보고 지나갈걸 그랬다. 드디어 새로 추가된 데이터를 가져왔다. 하지만 변경되거나 삭제된 데이터는 그대로 유지되고, 인터렉션으로 상태가 변경되서야 새로운 데이터가 들어왔다. 나는 무엇을 해야하는가.
ReactQueryDevTools
일단 이것도 refetch된 새로운 데이터를 바로 못가져오고 있는게 문제였기 때문에, 그 과정을 알아보고자 ReactQueryDevTools를 설치했다. useMutation이 onSuccess 되었을때 어떤 처리를 해줘야하는데, 어떤 처리를 해줘야겠는지 모르겠다. 그래서 일단 reset을 눌렀더니, refetch된 데이터를 잘 가져왔다. 역시 디버깅 도구가 답이었다.
cacheTime이 gcTime으로 변경된 이유
cacheTime이 캐시에서 데이터를 보유하는 시간으로 받아들이는 경우가 많아 gcTime(garbage collecter)로, 가비지 컬렉션을 수행하는 주기임을 인식하도록 명칭을 변환하였다.
+ staleTime은 사용가능한 상태를 유지하는 시간
onError가 사라진 이유
tanstack query v5에서 useQuery의 onSuccess, onSettled, onError는 예상대로 동작하지 않을 가능성이 높아 사라졌다. 컴포넌트 구조에 따라서 각각의 콜백이 여러번 호출될 수 있고 해당 콜백에서 상태 동기화를 많이 했는데, 이는 설계상 의도한 것이 아니었지만 상태 동기화를 하는데 적절한 위치로 보여 많은 사람들이 안티 패턴을 사용하게 되어 제거되었다.
에러를 각각의 훅에서 잡는 것이 아니라, queryClient 등 전역에서 잡아야한다. 에러바운더리와 서스펜스와 함께 사용하면 확실히 편하다.
refetch, invalidateQueries, reset의 차이
refetch 함수는 특정 쿼리를 다시 실행하여 데이터를 새로 고친다. 현재 데이터를 무시하고 서버에서 최신 데이터를 가져와서 캐시를 갱신한다. 리렌더링까지 시키지는 않는다.
invalidateQueries는 특정 쿼리에 대한 캐시된 데이터를 무효화시킨다. 따라서 다음번에 해당 쿼리를 다시 호출하면 서버에서 새로운 데이터를 가져와 캐시를 갱신한다.
rest은 모든 캐시된 데이터를 제거하고 모든 쿼리를 초기 상태로 리셋한다. 전체 애플리케이션의 상태를 초기화할 때 사용할 수 있다.
식자재를 만들거나 삭제할 때가 아닌 이상 돌아가긴 하기 때문에 우선순위에서 계속 밀리면서 일주일이나 잡고 있었다. 생각보다 해결책이 직관적이었지만 CRUD가 완벽하게 돌아가는걸 확인하니까 그제서야 편안해졌다. 사실 프론트분들이야 API 요청해오고 처리를 잘못하셨구나-하고 생각하겠지만, 다른 직군분들은 안되는거에만 집중할게 눈에 보여서 계속 잡고 있었다.