react query mutation의 onError

J·2025년 5월 6일
1

웹 공부

목록 보기
19/19
post-thumbnail

사용할 수 있는 onError 종류

  1. QueryClient -> defaultOptions -> mutations -> onError

    const queryClient = new QueryClient({
      defaultOptions: {
        mutations: {
          onError: (error) => {
            console.log("🟥 [defaultOptions onError]", error);
            return;
          },
        },
      },
    });
  2. QueryClient -> mutationCache -> onError

      const queryClient = new QueryClient({
        mutationCache: new MutationCache({
          onError: (error) => {
            console.log("🟥 [MutationCache onError]", error);
            return;
          },
        }),
      });
  3. useMutation -> onError

    const mutation = useMutation({
      mutationFn: async () => {
        //...
      },
      onError: (error) => {
        console.log("🟧 [useMutation onError]", error);
      },
    });
  4. useMutation -> mutate() -> onError

    const mutation = useMutation({
      mutationFn: async () => {
        //...
      },
    });
    
    //...
    mutation.mutate(undefined, {
    	onError : ()=>{
        console.log("🟨 [mutate onError]", error);
      }
    })

실행 순서

QueryClient.mutationCache 객체의 onError 가 가장 먼저 호출되고
useMutation의 onError가 그다음으로 호출되고
mutate()의 파라미터로 전달된 onError가 마지막으로 호출된다.

QueryClient.defaultOptions.mutations의 onError는 useMutation의 onError 가 없을 때 대신 호출 할 수 있는 callback이다.

테스트

테스트 코드

react + react query + axios 기반의 간단한 테스트 코드를 작성해 보았다.

 const queryClient = new QueryClient({
   defaultOptions: {
     mutations: {
       onError: (error) => {
         console.log("🟥 [defaultOptions onError]", error);
         return;
       },
     },
   },
   mutationCache: new MutationCache({
     onError: (error) => {
       console.log("🟥 [MutationCache onError]", error);
       return;
     },
   }),
 });

 function App() {
   const mutation = useMutation({
     mutationFn: async () => {
       // 500 에러를 발생시키는 api 호출
       await axios.get("https://httpstat.us/500");
     },
     onError: (error) => {
       console.log("🟧 [useMutation onError]", error);
     },
   });

   const handleClick = () => {
     mutation.mutate(undefined, {
       onError: (error) => {
         console.log("🟨 [mutate onError]", error);
       },
     });
   };

   return (
     <div style={{ padding: "2rem" }}>
       <h1>React Query onError 테스트</h1>
       <button onClick={handleClick}>에러 발생시키기</button>
     </div>
   );
 }

 export default function WrappedApp() {
   return (
     <QueryClientProvider client={queryClient}>
       <App />
     </QueryClientProvider>
   );
 }

테스트 1

에러 발생 버튼 클릭시 log

테스트 2

useMutation의 onError에 주석 친 다음 버튼 클릭시 log

useMutation의 onError가 호출되는 타이밍에 defaultOptions의 onError가 실행되는 것을 볼 수 있다.

react query에서 제공하는 다양한 onError에 관심사를 잘 나눠서 로직을 구현하면 에러 상황을 잘 핸들링 할 수 있을것 같다.

profile
꾸준한 노력파 개발자의 이모저모

1개의 댓글

comment-user-thumbnail
2025년 5월 7일

포스팅을 중간 정도까지 읽었을 때는 onError에 대해서
처음 알게되는 내용이라고 생각했었는데
읽는 중에 갑자기 떠올랐습니다! 예전에 이것과 관련해서
J님과 함께 onError 작업했던게 기억이 나네요!
그 때는 useMutation에 작업했었던거 같네요
생각해보면 onError의 호출 순서는 그 때의 저는 생각 못했던거 같습니다!
react query 내용은 오랜만에 다시보니 반갑네요!
기억이 아직 남아있어서 다행이라는 생각이 드네요 ㅎ..ㅜ

답글 달기