useQuery가 undefined를 리턴할 때 임시방편!

이진희·2022년 3월 23일
0

graphql-challenge

목록 보기
1/2

내 상황

  • useQuery에 variables로 필요한 값을 넣어서 사용
    * 페이지가 렌더링되자마자 패치할 필요없고, 다른 query의 응답이 왔을 때 패치하면 돼서 skip:true로 두어 최초 실행을 막음
  • 의도한 시기에 fetch가 일어나게 하기 위해서 refetch함수를 받아 필요할 때 호출
  • 그런데 다른곳에선 다 정상적으로 동작하던 useQuery훅과 refetch가 한 쿼리에서만 이상하게 동작. data로 undefined를 반환한다..!

아주 바보같은 짓을 했다. 그냥 useLazyQuery를 사용하면 됨...! 모두 useLazyQuery훅을 사용하면 깔끔하게 해결 될 문제이다. 그래도 아폴로클라이언트 캐싱 방식에 대해선 좀 공부해봐야 할 것 같다.

발생한 오류

  • chrome의 네트워크 탭에서는 정상적으로 데이터를 받아온 것을 볼 수 있음.

  • 막상 console에 가져온 데이터값을 찍어보면 undefined가 뜸

의심하고 있는 곳

  • apollo-client 캐싱문제. 그러나 캐시되어 있는 내용 자체가 없어서 캐시문제는 아닌 것으로 확인(fetchPolicy에서 캐시를 사용하지 않게 해도 똑같음)
  • 최신버전 @apollo/client에 나와 같은 오류를 겪고 있는 사람들이 많고, 다운그레이드를 해보라는 의견이 많아서 3.0.2버전으로 다운그레이드해봤지만 해결 불가능
  • data 불러오는 것만 문제인가 싶어서 loading, data, error가 정상적으로 값이 바뀌는지 확인해봤는데 loading은 false값만 유지하고있고, data와 error에는 undefined값이 들어감을 확인 => gql을 잘못작성했나 확인했지만 문제 없음. 동일하게 작성한 다른 쿼리는 정상 작동.
  • apollo client 공식문서의 useQuery hook 부분에서 하나 이상의 오류가 발생했을 때 data가 undefined로 설정된다는 내용을 확인. 그러나 error또한 undefined인 것을 확인...

임시방편

  • refetch를 실행했을 때 Promise객체를 반환하는 것을 보고 일단은 async/await를 이용해서 비동기 처리를 해보기로 했다.

    (onCompleted에서 출력한 데이터는 여전히 undefined고 async/await를 이용했을 때는 정상적인 값을 출력하고 있는 것을 볼 수 있다.)

코드

gql 쿼리

export const GETALLPAGE = gql`
  query getAllPage($workSpaceId: Float!) {
    getAllPage(workSpaceId: $workSpaceId) {
      children
      isRoot
      level
      pageId
      title
    }
  }
`;

useQuery 훅(refetch를 이용)

const { loading: getAllPagesLoading, refetch: getAllPages } = useQuery(
    GETALLPAGE,
    {
      onCompleted: (data) => {
        console.log("야아아아아앙", data);  ** 😭=>이부분에서 undefine 출력됨 **
      },
      onError: (e) => console.log("나 실패", e),
      skip: true,
    }
  ); 

async/await 이용

 (async () => {
            const data = await getAllPages({
              workSpaceId: +data.getAllWorkSpace[0].id,
            });
            console.log(data); => 여기서는 정상 출력😳
          })();

추가 공부사항

  • 아직 정확한 원인이 뭔지 몰라서 일단 그것부터 알아내야할 것 같다.
    임시방편으로는 async/await를 활용하는 수밖에는 없어보인다.
  • useQuery훅을 사용했을 때 onCompleted, onError는 콜백함수로 사용되어 데이터 패칭이 완료되면 그 때 실행되는 것으로 알고있는데 이게 아닌건지,, 한 번 찾아봐야할 것 같다!
profile
슬로우 스타터

0개의 댓글