[Tanstak-Query] Query Status - isSuccess 파해치기

kyoung·2024년 6월 12일

개요

이번에 진행한 프로젝트에서 코치님의 추천으로 Tanstack Query를 사용했다.
그 중, 코치님의 isSuccess에 대한 설명이 인상적으로 남아 이를 정리 해보고자 한다.

Query Sataus?

Tanstack query에는 두 가지 status가 있다. Fetch StatusQuery Sataus.
그중, 공식문서를 보면 Query Sataus의 설명은 다음과 같다.

Returns

  • status: QueryStatus
    • Will be:
      • pending if there's no cached data and no query attempt was finished yet.
      • error if the query attempt resulted in an error. The corresponding error property has the error received from the attempted fetch
      • success if the query has received a response with no errors and is ready to display its data. The corresponding data property on the query is the data received from the successful fetch or if the query's enabled property is set to false and has not been fetched yet data is the first initialData supplied to the query on initialization.
  • 쿼리시도가 완료되지 않은 경우 pending
  • 쿼리를 시도한 결과 오류가 발생하면 error
  • 쿼리가 오류 없이 성공적으로 응답을 받아온 경우 success

쉽게 말해, 쿼리로 받아온 data의 상태를 나타내는 값이다.

isSuccess

isSuccess가 뭔데?

//usequery 예시
const {
  data,
  error,
  status,
  fetchStatus,
  isLoading,
  isFetching,
  isError,
  refetch,
  // ...
} = useQuery({
  queryKey: ["whoAreYou"],
  queryFn: getWhoAreYou,
});

isLoading isFetching isError 등의 값들은 이 상태값으로부터 파생되며 boolean 값을 가진다. 만약 위의 쿼리 응답이 성공적이고, 데이터를 표시할 준비가 되어 있다면 isSuccess === true 일 것이다.

그러나!

//AchievementsBox.tsx
export default function AchievementsBox() {
  const {
    data: myMountains,
    isSuccess,
    isError,
    isFetched,
  } = useQuery({
    queryKey: ['myMountains'],
    queryFn: getMyMountains
  });
  
...

    {isSuccess && <MyMountainList data={myMountains} /> }
 )}

getMyMountains 호출에 성공했을 경우, <MyMountainList />를 보여주는 코드이다.
여기서 isSuccess는 "호출에 성공했는가?" 또는 "200 status를 받아왔는가?"를 의미하는 것 같이 보인다. 물론 실제로도 뜻은 맞으나, 엄밀히 따지자면 우리가 바라는 "시점"과는 다른 의미를 가진다.

한번도 호출된적 없는 쿼리에 대해, 해당 쿼리가 200 응답을 한 경우 isSuccess == true가 된다.

예시를 들어서 설명 해 보겠다.

//쿼리 호출 전
isSuccess = false, isFeched = false, isError = undefined

//호출 최초 성공
isSuccess = true, isFeched = true, isError = false

//호출 두번째 성공
isSuccess = true, isFeched = true, isError = false

//호출 세번째 실패
isSuccess = true, isFeched = true, isError = true

아하! isSuccess는 최초 호출에 성공했을 경우 true가 된다.
즉, 조건을 isSuccess로만 둘 경우 최초에 호출했을 경우에만 의도대로 동작한다는 것이다.

그렇다면, 어떤 조건을 두어야 우리가 바라는 의도와 같아질까?

엄격하게 하고 싶다면 isFetched && !isError

//AchievementsBox.tsx
export default function AchievementsBox() {
  const {
    data: myMountains,
    isError,
    isFetched,
  } = useQuery({
    queryKey: ['myMountains'],
    queryFn: getMyMountains
  });
  
  const isSuccess = !isError && isFetched;
  
  return (
  <>
    {isSuccess && <p> myMountains.length </p>} 개
  <>
 )}

isFetched && !isError 를 사용하면 된다.
이렇게 사용할 경우 isSuccess만 사용했을 때 보다 더 엄격하게 조건을 설정할 수 있다.

isLoading? isFetching?

위의 isSuccess와 비슷한 경우이다.

쿼리를 호출하고 있는 경우 == isFetching

최초로 쿼리를 호출하고 있는 경우 == isLoading

즉, api를 호출하는 와중에 페이지에 스피너를 띄우고 싶다면

//AchievementsBox.tsx
export default function AchievementsBox() {
   const {
    data: myMountains,
    isError,
    isFetched,
    isFetching,
  } = useQuery({
    
...

{isFetching && <Spinner /p>}

isLoading 보단 isFetching을 사용하는 것이 조금 더 의도에 맞는 코드가 될 것이다.

 

0개의 댓글