ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이건 무효야! Query Invalidation
    FE/React Query 2023. 12. 6. 23:50

    React Query는 데이터를 캐싱하여 불필요한 API 호출을 줄여줍니다.
    useQuery로 데이터를 읽어오고, useMutation으로 데이터를 추가, 수정, 삭제할 수 있습니다.
    이때, useMutation으로 데이터를 변경한다고 해서 useQuery가 바로 데이터를 새로 읽어오지 않습니다.
    왜냐하면 캐싱 한 데이터를 계속 사용하고 있기 때문입니다.
    자세히 알아보기 전에 react query의 데이터 흐름을 잠깐 먼저 살펴보겠습니다.

    React Query의 데이터 흐름

    react query에서의 데이터 상태는 아래와 같은 흐름을 가지고 있습니다.

    1. fetching: 데이터 요청 상태
    2. fresh: 데이터가 만료되지 않은 상태
    3. stale: 데이터가 만료된 상태
    4. inactive: 사용하지 않는 상태
    5. delete: 데이터가 제거된 상태

    Invalidation

    최신 데이터를 받아오려면 invalidation을 통해 캐싱된 데이터를 무효화하고 새로운 데이터를 가져와야 합니다.

    QueryClient의 invalidateQueries 메서드를 사용하면 쿼리를 stale 상태(만료된 상태)로 표시하고 다음에 쿼리를 사용할 때 다시 가져옵니다.

    만약, 현재 렌더링 되고 있는 상태라면 즉시 데이터를 새로 가져옵니다.

    // 전체 쿼리를 무효화
    queryClient.invalidateQueries()
    // 쿼리 키가 `todos`로 시작하는 쿼리들을 모두 무효화
    queryClient.invalidateQueries({ queryKey: ['todos'] })

    invalidateQueries vs removeQueries

    QueryClient에는 캐싱된 데이터를 삭제하는 removeQuereies라는 메서드도 존재합니다.
    그렇다면 언제 invalidateQueries를 쓰고 언제 removeQueries를 쓰는 게 좋을까요?
    removeQueries는 invalidateQueries와 다르게 그 즉시 캐싱된 데이터를 삭제합니다.
    단, 만약 해당 쿼리가 이미 실행 중이라면 여전히 실행 중인 상태로 유지되며, 해당 쿼리에 대한 처리가 완료될 때까지 영향을 받지 않습니다.
    그리고 쿼리를 완전히 삭제하기 때문에, 처음부터 다시 가져와야 한다는 특징이 있습니다.
    이 점이 invalidateQueries와 가장 다른 점입니다.
    invalidateQueries는 이전 데이터를 아직 가지고 있기 때문에, 새로 가져오기 전까지 이전 데이터를 보여줍니다.
    새로 데이터를 들어오면 이전 데이터와 교체를 해주기만 하면 됩니다.
    removeQueries는 이전 데이터가 없으므로, 새로 데이터를 가져오기 전까지 보여줄 수 있는 게 없습니다.

    resetQueries

    그렇다면, 이전 데이터를 보여주고 싶지 않다면, removeQueries를 쓰고 refetch를 하면 되는 걸까요?
    그래도 되지만, resetQueries라는 메서드를 사용하는 방법도 있습니다.
    resetQueries는 캐싱된 데이터를 삭제하고 다시 요청합니다.
    그래서 앞서 remove를 하고 다시 refetch를 해야 하는 상황이라면 resetQueries를 쓰는 것이 좋습니다.

      const queryClient = useQueryClient();
      const { data, refetch } = useQuery({
        queryKey: ['queryKey'],
        queryFn: () => queryFn(),
      });
      
      // remove 후 refetch
      const removeAndRefetchQuery = () => {
        queryClient.removeQueries({
          queryKey: ['queryKey']
        });
        refetch();
     });
     
     // reset
     const resetQuery = () => {
       queryClient.resetQueries({
         queryKey: ['queryKey']
       });
     });

    후기

    useMutation으로 데이터를 조작하고 난 후에도 렌더링 되는 데이터는 바뀌지 않아서 관련 내용을 찾아보았습니다.
    단순히 캐싱된 데이터를 삭제해 주면 된다고 생각하였지만, 캐싱된 데이터를 무효화하거나 삭제를 하는 경우를 잘 파악하여 그에 맞는 메서드를 쓰는 것이 중요하다는 것을 알게 되었습니다.
    또한, 이러한 기능들을 잘 활용하면 더욱 안정적인 캐싱 메커니즘을 얻을 수 있고, 데이터 관리에서도 효율성을 크게 향상할 수 있다는 것을 알게 되었습니다.

    참고

    https://tanstack.com/query/v4/docs/react/guides/query-invalidation

    https://medium.com/@neungszad/what-is-difference-between-clear-vs-removequeries-vs-resetqueries-vs-queryinvalidate-from-384a53e79e06

    https://github.com/TanStack/query/discussions/3169

Designed by Tistory.