내 상황
- 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는 콜백함수로 사용되어 데이터 패칭이 완료되면 그 때 실행되는 것으로 알고있는데 이게 아닌건지,, 한 번 찾아봐야할 것 같다!