본문 바로가기

개발/React

(짧) Tanstack/Query(구 React-Query)를 사용할 때 미세 팁

반응형

 

 

 

  • Tanstack/Query(구 React-Query)의 useQuery를 사용할 때, 실행에 대한 Callback을 선언하는 부분이 queryCache와 useQuery의 Callback이 있는데 이 둘을 같이 사용한다면 실행 순서는 [queryCache에 작성된 콜백] -> [사용처의 콜백함수] 가 된다.

 

  • Tanstack/Query(구 React-Query)의 useMutation에는 함수실행 후 반환해주는 mutate의 onSuccessuseMutation 선언 시에 바로 주입해줄 수 있는 onSuccess가 있다. 이 둘은 미세하게 차이가 있는데, mutate의 onSuccess는 지면에서 사용하는 onSuccess이기때문에 지면이 이동하는 등 사용처의 코드가 unmount되는 상황에서는 정확하게 실행되지 않을 가능성이 있다고 한다. 따라서 반드시 실행되어야하는 콜백함수라면 useMutation의 선언 시에 주입해주는 것이 좋다.

 

  • Tanstack/Query(구 React-Query)를 활용하는 패턴 중 특정 액션시에만 useQuery를 호출해야만 하는 경우 enabled를 false로 주고, 특정 액션을 트리거로 refetch 하는 방식을 사용하기도 하는데, 이 방식을 사용할 때 쿼리에서 특정 액션으로부터 데이터의 변화를 일으킨 후 바로 refetch를 하게되면 유효하지 않다. 이는 query가 렌더된 시점을 기준으로 상태를 가지고있기 때문에 비동기배치 이후 다시 렌더된 시점이 되어야 data가 최신화되어, useEffect를 활용하여 이 문제를 해결할 수 있다

 

  • Tanstack/Query(구 React-Query)의 useQuery에서 refetchOnWindowFocus옵션은 false를 제외 true, always가 나누어져 있는데, true라면 staleTime 내에 있다면 네트워크 재요청을 하지 않도록 하고, always라면 staleTime에 관계없이 항상 네트워크 재요청을 하도록 한다. 또한 refetchInterval은 true, false만 존재하며 true인 경우 별도 체크 없이 항상 네트워크 재요청을 한다.

 

  • Tanstack/Query(구 React-Query)의 useMutation을 사용할 때 useMutation에 있는 mutationFn이 끝날때까지 호출부에서의 isLoading이 true로 유지되는데, 추가적으로 onSuccess와 onSettled에도 Promise가 존재한다면 이에 대한 실행 역시 기다린 후에 isLoading값이 false로 변환되고, 이후에 호출부에 존재하는 mutate에 걸려있는 onSuccess가 실행된다.

    ( 호출부의 mutate실행 -> isLoading값 true 전환 -> useMutation의 mutationFn -> useMutation의 onSuccess -> useMutation의 onSettled -> isLoading값 false 전환 -> 호출부의 onSuccess실행)

 

  • 위의 상황에서 한 발자국 더 나아가 추가적으로 수행해주어야하는 로직이 존재한다면, useMutation의 onSuccess에 로직을 두어 호출부에서는 useMutation으로부터 반환받은 mutate만 사용함으로써 mutation 역시도 선언적으로 사용하여 특정 로직을 사용할 수도 있다. 다만 이러한 상황에서는 유연성이 떨어지기때문에 여전히 호출부의 mutate에 onSuccess를 두어 명령형으로 추가 액션을 처리하여 서버호출에 대한 액션은 useMutation의 mutationF에 완벽하게 위임하고, 이를 사용하는 사용처의 mutate의 onSuccess에서 클라이언트 로직을 수행하여 책임을 분리하는 관점도 있기에 프로젝트 상황에 따라 알맞게 사용하는 것이 좋다.

 

  • useQuery와 useMutation의 사용을 생각할 때에는 단순히 get, post에 따라 나누기 쉬운데, 이러한 관점은 너무 확장성이 떨어진다. 한발짝 더 나아가 생각해보면 useQuery는 특정 로직을 선언적으로 사용할 때, useMutation은 특정 로직을 명령적으로 사용할 때 사용한다고 생각하면 더 좋은 접근이 가능하다. 
  • 또한 위의 접근 방식에서도 조금 더 다양한 각도로 고민해본다면 해당 Query가 반환받는 값에만 관심이 있는지에 대한 관심사 여부의 관점으로 생각해보는 것도 좋다. Query에서 사용하는 queryFn에 특정 API 하나만 사용하게된다면 v4까지는 지원했던 onSuccess나 onError를 통해 로직을 체이닝으로 사용할 수 있지만, 이는 v5부터는 deprecated 된 패턴이기때문에 다른 방법을 고민해야한다. 따라서 Query가 반환받는 값에만 관심이 있다면 queryFn 안에서 이에 대한 체이닝 로직들을 모두 수행한 뒤 반환해주는 것도 방법이고, Query가 수행하는 추가 로직에 대해 지면에서 알아야한다면 (관심사에 포함된다면) Mutation으로 전환하여 명령적으로 onSuccess와 onError의 상황에 대해 명시하여 사용할 수 있다.
반응형