Ayden's journal

React Query와 AXIOS

상황

서버 상태관리를 React Query로 관리하기 시작하면서 기존에 fetch로 만들었던 리퀘스트 함수들을 AXIOS로 싹 갈아 엎기로 했다. AXIOS 자체가 러닝 커브가 낮은 편이라 갈아 엎는 작업 자체는 금방 끝났다. 그런데 npm run dev를 때리자 getServerSideProps에서 즉시 에러가 튀어나왔다.

 

문제

Error serializing .dehydratedState.queries[0].state.data.headers returned from getServerSideProps in "/mydashboard".

"/mydashboard"페이지에서 사용한 getServerSideProps 함수에서 serializing 에러가 발생했다. 메세지만 놓고 보면 아주 단순한 에러이다. 여기서 serializing은 '직렬화'라고 번역되는데, 컴퓨터 메모리 상에 존재하는 객체(Object) -> 문자열(string) 로 변환하는 작업을 말한다. 그 반대는 Deserialization 혹은 Parse라고 부르고 '역직렬화'라고 번역한다. JSON.parse() 메소드가 하는 일이 바로 역직렬화이다.

dehydratedState에 대하여 정확히 알지는 못하지만, react query를 컴포넌트가 props로 넘겨받는 과정에서 탈수 과정을 거치는데 그에 관한 이야기라고 생각했다. 따라서 나는 다른 부분은 고려하지 못하고 dehydrate 과정에서 무언가 문제가 발생했겠거니 생각하며 열심히 삽질을 시작했다.

 

해결

결론부터 말하자면 내 초기 아이디어가 그 자체로 잘못된 건 아니었다. 이 에러는 dehydrate 과정에서 직렬화 하는 중 문제가 발생했기에 튀어나온 것이다. 그런데 왜 문제가 발생한 걸까? 이를 위해서는 JS에서 JSON 데이터로 직렬화하는 방식을 알아야 한다. 객체를 JSON 데이터로 변환하는 과정에서 메서드나 던더 프로토, getter/setter 등과 같이 JSON으로 변경할 수 없는 프로퍼티는 모두 무시된다.

AXIOS Instance가 반환하는 값을 그대로 dehydrate에 넣었다. 그런데 반환하는 값에 무언가 JSON으로 변경할 수 없는 프로퍼티가 존재하고, 그것을 dehydrate하려고 시도했기 때문에 이러한 직렬화 오류가 발생한 것이라 생각된다.

 

이러한 오류를 해결하려면 크게 두 가지 방법을 사용할 수 있다. 좀 더 널리 알려진 해결 방법은 getServerSideProps에서 AXIOS가 리턴한 값을 가지고 있는 queryClient를 JSON.parse(JSON.stringify(dehydrate(queryClient)))와 같이 직렬화 ➠ 역직렬화를 하여 문제가 될만한 놈들을 사전에 걷어내는 것이다. 하지만 나는 이것이 '깔끔한' 해결 방법이라고는 생각하지 않는다. 좀 지저분하달까?

내가 선택한 해결 방법은 AXIOS Instance를 request라는 함수로 한 번 감싼 다음, 필요한 데이터 ─ data, status 등 ─ 만을 반환하게 하는 것이다. 이 방법 역시도 완전한 해결책이라고는 생각하지 않는다. AXIOS 리턴 값 중에서 반환되지 않는 값이 있다면 그 때마다 계속 request 함수가 반환하는 값을 건드리게 될 테니까. 하지만 직렬화 ➠ 역직렬화하는 것보다는 낫다고 생각한다.

결국은 각자의 취향 문제로 귀결될 것 같지만.

 

결론

결론이랄까… '와! 이 문제를 해결했다!'라고 선언하기에는 아무래도 조금 거식한 데가 있다. dehydrate 함수가 하는 일이 정확히 어떻게 되는지 모르기 때문이다. 공식문서를 읽어봐도 시원하게 '이게 이런 식으로 동작해서 직렬화 오류가 발생한 거구나'하는 식의 깨달음은 얻지 못했다. 다만 한 가지 확실한 것은 이게 JSON.stringify 처럼 동작하지는 않는다는 거겠지…

문제를 해결하면 찾아봐야 할 게 또 생기고, 이렇듯 배움에는 끝이 없다는 게 오늘의 결론인가보다.

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기