본문 바로가기

FrontEnd

리액트 쿼리 : 쿼리 상태 체크

반응형

원문 보기 : https://tkdodo.eu/blog/status-checks-in-react-query

 

쿼리 상태는 아래 4개 중 하나입니다

  • success : 쿼리가 성공했으며 이에 대한 데이터가 있습니다.
  • error : 쿼리가 실패했으며, 이에 대한 정보를 담은 에러가 설정되었습니다.
  • loading : 아직 쿼리 데이터가 없으며, 처음 로딩 중입니다.
  • idle : 사용이 설정되지 않아 쿼리가 실행된 적이 없습니다.

업데이트: React Query v4에서 idle 제거

isFetching 플래그는 요청 중일 때만 true지만, 내부 상태머신의 상태가 아님.
자세한 내용은 #13: Offline React Query 참조

로딩 상태, 오류 상태를 먼저 확인하기

명시적 사용자 상호작용 시에만 데이터를 (다시) 가져오는 솔루션에는 나쁘지 않은 방식입니다.

React-Query는 백그라운드에서 적극적으로 데이터를 다시 가져오며,

refetchOnMount, refetchOnWindowFocus, refetchOnReconnect 개념들은

서버와 클라이언트 상태를 정확하게 일치하기 위해 노력합니다.

 

따라서 아래와 같은 방식은 사용자의 UX를 혼란스럽게 할 수 있습니다.

많은 상황에서 백그라운드 리페치의 오류는 무시할 수 있지만, 아래 예제는 그렇지 않기 때문입니다.

const todos = useTodos()

if (todos.isLoading) {
  return 'Loading...'
}
if (todos.error) {
  return 'An error has occurred: ' + todos.error.message
}

return <div>{todos.data.map(renderTodo)}</div>

백그라운드 오류

많은 상황에서 백그라운드 다시 가져오기가 실패하면 자동으로 무시될 수 있습니다.

  • 사용자가 우리 페이지를 열고 초기 쿼리가 성공적으로 데이터를 로드합니다.
    • 한동안 페이지 탭에서 작업하다가 (브라우저) 탭을 전환하여 이메일 탭을 확인합니다.
    • 몇 분 후에  우리 페이지 탭으로 다시 돌아와서 React Query가 백그라운드 다시 가져오기를 수행합니다.
      • 가져오기가 실패합니다.
  • 사용자는 목록 보기가 있는 페이지(아까 쿼리가 실패한)에 있고 세부 보기로 드릴-다운하기 위해 하나의 항목을 클릭합니다.
    • 이것은 잘 작동하므로 목록 보기로 돌아갑니다. (캐시에 데이터가 있기 때문)
    • 다시 세부 정보 보기로 이동하면 캐시의 데이터가 표시됩니다.
    • 백그라운드 다시 가져오기가 실패하는 경우를 제외하고는 훌륭합니다.
두 상황 모두에서 쿼리는 다음 상태가 됩니다.
{
  "status": "error",
  "error": { "message": "Something went wrong" }, // 에러도 있고
  "data": [{ ... }] // 데이터도 있고
}

보시다시피 오류와 오래된 데이터를 모두 사용할 수 있습니다.

이것이 React Query를 훌륭하게 만드는 것입니다. stale-while-revalidate 캐싱 메커니즘을 수용합니다.

즉, 데이터가 존재하는 경우 데이터가 오래된 경우에도 항상 데이터를 제공합니다.

 

이제 화면에 무엇을 표시할지 결정하는 것은 우리에게 달려 있습니다.
  • 오류를 보여주는 것이 중요합니까?
  • 오래된 데이터가 있는 경우에만 표시하는 것으로 충분합니까?
  • 백그라운드 오류 표시기를 사용하여 둘 다 표시해야 합니까?

이 질문에 대한 명확한 답은 없습니다. 사용 사례에 따라 다릅니다.

그러나 위의 예제의 사용사례의 경우, 데이터가 오류 화면으로 대체된다면 다소 혼란스러운 사용자 경험이 될 것이라고 생각합니다.


React Query는 지수 백오프를 사용하여 기본적으로 실패한 쿼리를 세 번 재시도 합니다.

  • 따라서 오래된 데이터가 오류 화면으로 대체될 때까지 몇 초가 걸릴 수 있습니다.
  • 백그라운드 데이터 가져오기 표시기가 없는 경우 이는 정말 당혹스러울 수 있습니다.

데이터 가용성을 먼저 확인하기

이전의 사용 사례를 고려하면, 해당 방법이 더 적절합니다만,

앞서 말했듯이 사용 사례에 크게 의존하기 때문에 무엇이 옳은지에 대한 명확한 원칙이 없습니다.

공격적인 리패칭이 가져오는 결과를 알고 있어야 하며,

간단한 할일 예제를 엄격히 따르기 보다는, 우리의 사용사례에 따라 코드를 작성해야 합니다/

const todos = useTodos()

if (todos.data) {
  return <div>{todos.data.map(renderTodo)}</div>
}
if (todos.error) {
  return 'An error has occurred: ' + todos.error.message
}

return 'Loading...'

 

 
반응형