Skip to content

Tanstack Query 의 QueryErrorResetBoundary

Yechan Jung edited this page Nov 20, 2023 · 3 revisions

Tanstack Query


Tanstack query는 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 쉽게 사용하기 위한 라이브러리 입니다.

Tanstack Query의 장점 / 사용 이유

  1. 데이터 가져오기 및 캐싱: 데이터를 가져오고, 캐싱하며, 업데이트하는 과정을 단순화합니다. 자동 캐싱을 지원하여 수동 설정의 필요성을 줄이고 데이터 관리를 효율적으로 합니다.
  2. 자동 데이터 재요청: 컴포넌트가 다시 마운트되거나 창이 다시 포커스될 때 자동으로 데이터를 재요청합니다. 이를 통해 추가 코딩 없이도 항상 최신 정보를 유지할 수 있습니다.
  3. 백그라운드 데이터 동기화: 백그라운드에서 데이터를 동기화하여 로딩 시간을 줄이고 앱의 반응성을 향상시켜 사용자 경험을 개선합니다.
  4. 내장된 오류 처리: API 요청에서 발생하는 오류를 관리하고 사용자에게 적절한 피드백을 표시하는 내장 오류 처리 메커니즘을 제공합니다.
  5. 개발자 도구: React Query는 쿼리와 변형의 상태를 디버깅하고 시각화하는 데 도움이 되는 개발자 도구 세트를 제공합니다. 이는 복잡한 애플리케이션에서 순수 자바스크립트보다 큰 장점입니다.
<ReactQueryDevtools initialIsOpen />의 코드를 QueryClientProvider 내부에 넣음으로써 아래와 같은 Dev Tool을 이용할 수 있습니다.
tanstack_query_devtools

6. 낙관적 업데이트: POST나 PUT 요청과 같은 변형이 성공한 것처럼 UI를 즉시 업데이트하고 오류가 발생하면 되돌리는 낙관적 업데이트를 지원합니다. 이는 앱이 더 빠르게 느껴지게 하여 사용자 경험을 향상시킵니다.

7. 성능 향상: 서버 상태 관리, 캐싱, 데이터 가져오기를 효율적으로 관리함으로써 특히 복잡한 데이터 관리가 필요한 시나리오에서 애플리케이션의 성능을 크게 향상시킬 수 있습니다.

현재 백준룸즈의 기획에서는 낙관적 업데이트 등 위의 기능이 아주 유용할 것으로 생각되어 라이브러리를 사용하기로 하였습니다.





Tanstack Query와 React의 Suspense

일반적으로 Tanstack Query를 이용한 Component 작성시 아래와 같이 작성합니다.

function Todos() {
  const { isPending, isError, data, error } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
  })

  if (isPending) {
    return <span>Loading...</span>
  }

  if (isError) {
    return <span>Error: {error.message}</span>
  }

  // We can assume by this point that `isSuccess === true`
  return (
    // Some components to render...
  )
}

하지만 QueryErrorResetBoundary을 이용한다면 더 선언적으로 Error와 Loading상태를 사용 할 수 있습니다.
그러기 위해서는 먼저 React.Suspense와 ErrorBoundary에 대해 알 필요가 있습니다.


React의 Suspense는 하위 컴포넌트들의 로딩이 끝나기 전까지 Fallback을 렌더링합니다.

Tanstack Query의 QueryErrorResetBoundary는 하위 컴포넌트들이 에러가 일어났을 때 re-rendering을 지원합니다. react-error-boundary의 ErrorBoundary와 함께 사용하면서 컴포넌트의 경계 내에서 에러가 일어났을 때 reset할 수 있습니다.

export function DataContainer({ queryKey, fetchData }: DataContainerProps) {
  return (
    <QueryErrorResetBoundary>
      {({ reset }) => (
        <ErrorBoundary onReset={reset} FallbackComponent={ErrorFallback}>
          <React.Suspense fallback={<LoadingFallback/>}>
            <DisplayData queryKey={queryKey} fetchData={fetchData} />
          </React.Suspense>
        </ErrorBoundary>
      )}
    </QueryErrorResetBoundary>
  );
}

위와 같이 코드를 작성하면 해당 컴포넌트의 fetch에서 Error가 발생 할 경우 ErrorFallback을, 로딩 중일 때는 Suspense의 LoadingFallback을 렌더링 할 수 있습니다.

위의 코드의 장점으로는

  1. 선언적 접근이 가능합니다 : 기존의 방법으로는 명령적이고 반복적으로 코드를 선언하게 됩니다.
  2. 관심의 분리 : 기존 컴포넌트에서는 일반적인 경우 렌더링만 신경 쓰고, 에러와 로딩 처리에 대해서는 다른 컴포넌트가 렌더링을 담당하게 됩니다.
  3. 컴포넌트 경계 관리 : ErrorBoundary와 Suspense를 이용하면 에러와 로딩 렌더링의 범위를 직접 정할 수 있게 됩니다.
  4. 에러 캡쳐링 : ErrorBoundary는 하위 컴포넌트의 모든 Error를 캡쳐링 하기 때문에, 에러가 관리가 용이할 수 있습니다.

CodeSandbox Example

Clone this wiki locally