개인공부/라이브러리

React Query의 throwOnError: false 설정

minseokiim 2025. 3. 14. 14:49

정말 오랜만에 작성하는 블로그 ..ㅎㅎ


몇 달 전 에러바운더리에 대해서 글을 작성했었는데, 이번에 관련된 작업을 하게 되었다.
 
에러바운더리는 상단 컴포넌트에 설정해두어야 하고, 해당 영역에 에러가 발생한 경우에 대체 ui로 가려지는 역할을 한다.
이 기능을 통해서  깨진 ui만 대체되어, 유저는 다른 기능들 사용이 가능하다.
 
하지만, 이 기능이 동작하면 안되는 경우가 존재했다.
해당 ui로 가려지지 않고, 그 버튼 하나만 보여지지 않으면 되는 부분이었는데 중요도 낮은 기능 하나 때문에 페이지 진입 문제가 발생했다.
설상가상으로, 분리할 수 없는 부분이어서 이 기능이 포함된 컴포넌트 전체 영역에 에러바운더리가 표출되는 문제까지 발생했다.
 
그래서, 이 버튼 하나만 비활성화 되게 하는 로직으로 변경하였다.
방법은 리액트 쿼리 내부에서 throwOnError: false 설정을 하는 것 이었다.
 


🤔 throwOnError: false 란?

React Query가 에러를 Error Boundary로 전파하지 않도록 하는 속성
에러는 여전히 발생하지만, React Query는 이 에러 정보를 쿼리 결과 객체에 저장해서 컴포넌트 내부에서 isError로 잡을 수 있음.
에러를 잡지만, 단지 에러를 React Error Boundary 전파할지 여부만 결정하는 속성이다!
 

export const use....Query = (...) => {
  return useQuery({
    queryKey: [...],
    queryFn: () => get...(...),
    select: (data) => data....,
    retry: false,    // 에러 발생한 경우 retry 되지 않게 설정
    throwOnError: false,  // 에러 바운더리로 가려지지 않게 설정
  });
};

 
여기서 중요한 점은, 이 방식은 useSuspenseQuery가 아닌 useQuery에서 사용해야한다는 점!
 
useSuspenseQuery는 자동으로 에러를 가장 가까운 Error Boundary로 던지는 반면, useQuery는 컴포넌트 내에서 에러를 처리할 수 있게 하기 때문이다.
즉, 에러바운더리로 던져서 생긴 문제였던 나에게는 해결할 수 없는 방식이다.
 
useSuspenseQuery는 항상 에러를 던지도록 설계되었기 때문에 throwOnError: false가 적용되지 않는다고 한다 ㅎㅎ
 
위에서 말했듯이, isError로 에러 발생 유무를 잡을 수 있기 때문에 컴포넌트 내부에서 분기처리도 가능하다.

 const { data, isError } = use...Query(....);
      ..
  return (
     ..
    {isError && (
          < ..... />
        )}
    ...
       )

 
이렇게 하면
1. 에러바운더리로 인해 가려지지 않음
2. 에러가 나도 진입 가능
3. 원하는 에러 처리를 내부에서 분기처리로 설정 가능

해결 !🍀


 
[ 에러바운더리 포스팅 ]

에러 바운더리 (Error Boundaries)

* 간단하게 적는 도입 이유: 가장 상단에서 페이지에 진입하게 되면, api를 여러 개 호출하는데한가지의 api 관련 에러 때문에 페이지 전체가 보이지 않는 에러가 생겼다.이 api는 하나의 작은 버튼

kmmk808.tistory.com