머리말
일단 제가 아는 선(현재 프로젝트에서 적용한)에서의 내용만 정리해보겠습니다. 틀린 부분이 있다면 바로 알려주세요!
그리고 사용하시다가 새로운 옵션이나 새로운 내용, 더 좋은 사용법을 알게되었다면 이 문서에 작성해주세요 😁
소개
react-query는 서버의 상태를 관리하는 라이브러리 이다.
공식사이트에서 말하는 서버의 상태란 아래와 같다.
- 클라이언트에서 제어하지 않는 원격에서 관리되고 유지되는 데이터
- 데이터 Fetching, Updating에 비동기 API가 필요
- 다른 사용자들과 공유되는 상태이기 때문에 내가 모르는 사이에 변경될 수 있음
- 신경쓰지 않으면 잠재적으로 out of date가 될 수 있음
- Is persisted remotely in a location you do not control or own
- Requires asynchronous APIs for fetching and updating
- Implies shared ownership and can be changed by other people without your knowledge
- Can potentially become "out of date" in your applications if you're not careful
사용 목적
내가 생각하는 react-query의 사용 목적중 하나는 기존 redux를 사용할 때 비동기 처리를 하기위해선
redux-thunk
나 redux-saga
를 사용해야 했는데 많은 양의 보일러플레이트 코드가 필요 했는데, react-query
를 사용하면 보일러플레이트 코드의 크기가 상당히 작아진다! 밑에 있는 예시 코드를 보면 조금 더 와닿을 것이다.사용 방법
초기 설정
초기 설정은 정말 간단하다. emotion의 ThemeProvider나 ContextAPI의 ContextProvider를 사용하는 것 처럼
QueryClientProvider
로 감싸주기만 하면 된다.우리 프로젝트에서 설정한 옵션인
refetchOnWindowFocus: false
(기본값은 true이다.)는 브라우저에 포커스가 될 때 마다 쿼리(API 요청 이라고 생각하면 된다.)가 발생하는데 이를 끄는 옵션이다. 이것은 데이터가 stale
한 상태가 아니라 fresh
한 상태로 유지하려는 특징이다. 예를 들어 사용자가 브라우저를 오랫동안 보지않고 다른일을 하고 있다가 다시 브라우저로 돌아 왔을 때 보이는 데이터는 시간이 오래 지났기 때문에
stale
한 데이터라고 볼 수 있다. 그래서 데이터를 fresh
하게 유지하기 위해 백그라운드에서 새로운 데이터 요청을 한다.위의 방법처럼 전역적으로 설정할 수도 있고 각각의 쿼리별로 disable할 수 있다.
이 설정을 false로 한 이유는 개발자도구를 켜놓고 개발을 하는데 이게 개발자도구를 사용하고 브라우저를 다시 클릭만 해도 API 요청이 돼서 일단은 꺼놨다. 팀원들과 협의 후 추후 설정이 필요하다.
기본 사용
일단 내가 사용했던 두 가지는
useQuery
와 useMutation
이다.- useQuery(queryKey, queryFunction, options) : 서버의 상태를 가져올 때 사용한다 (조회) 공식문서
- queryKey : 해당 쿼리의 유일해야 하는 키 값이다. 이 키 값으로 내부적으로 데이터를 캐시하고, 데이터를 자동으로 가져올 수 있게 하기 때문에 중요하다. 키는 문자열로 지정할 수도 있지만 다양한 형태로도 지정할 수 있다. (공식사이트) 예를 들어 어떤 리스트가 있고, 리스트 각각의 아이템을 조회할 때 그 아이템의 키 값을 활용하는 것 같다.
- queryFunction : 실질적으로 비동기 요청을 할 함수이다. 우리 프로젝트에서는 axios를 사용해서 비동기 요청하기 때문에 여러분들이 정의한 axios 함수를 import 하여 사용한다.
- options : 여러 옵션들을 설정할 수 있다.
- onSuccess : 해당 쿼리가 성공했을 때 콜백
- onError : 해당 쿼리가 실패했을 때 콜백,
그리고 여기서 아예 서버로부터 응답을 받을 수 없는 에러가 발생했을 경우 response가 undefined로 오는 경우가 있더라구요 그래서 response에 대해 undefined 처리를 한번 해줬는데 이렇게 처리하는게 맞는지 아직 확신이 안섭니다!
- retry : 쿼리가 실패하면 react-query는 자동으로 쿼리 요청을 3번 진행한다.
- 타입스크립트 타입 지정 : 이 부분은 vscode에서 직접 useQuery의 타입을 확인해보고 작성했다. 아래 내용은 추측한 것이기 때문에 잘못된 내용이 있으면 바로 수정할 예정!
- unknown : 쿼리를 요청할 함수의 타입이다. unknown인 이유는 어떠한 타입의 함수가 들어올 지 예상할 수 없어서 라고 생각했다.
- QueryError : 쿼리에서 에러가 발생했을 때 받을 데이터의 타입이다. 아래 코드에선 onError 콜백의 인자로 넘어오는 데이터의 타입
- QueryData : 쿼리가 성공했을 때 받을 데이터의 타입이다. 아래 코드에선 onSuccess 콜백의 인자로 넘어오는 데이터의 타입
- string : 쿼리 key의 타입
- useMutation(mutationFunction, options): 서버의 상태를 변경할 때 사용한다 (생성, 수정, 삭제) 공식문서 (전체적으로 useQuery와 사용법, 형태가 비슷하다.)
- mutationFunction : 비동기 요청할 함수이다.
- options : useQuery와 비슷한 옵션들을 설정할 수 있다.
- onSuccess : 해당 뮤테이션이 성공했을 때 콜백
- onError : 해당 뮤테이션이 실패했을 때 콜백
- 타입스크립트 타입 지정 : useQuery와 마찬가지로 vscode에서 직접 확인하여 작성했기 때문에 틀린 부분이 있다면 바로 수정할 예정!
- MutationData : 뮤테이션이 성공했을 때의 데이터 타입. onSuccess 콜백의 인자로 넘어오는 데이터
- MutationError : 뮤테이션이 실패했을 때의 데이터 타입. onError 콜백의 인자로 넘어오는 데이터
- unknown : mutationFunction의 인자로 넘어오는 데이터의 타입
- unknown : context의 타입 (react-query안에서 context라는 것을 사용할 수 있는데 아직 정확한 내용은 모르겠음)
마무리
일단 저도 깊게 학습하지 않아서 잘 쓰고 있는 것인지는 모르겠지만 쓰다가 더 좋은 방법이 있으면 차차 적용해 갈 계획입니다.
또한, 틀린 내용이 있을 수도 있으니 제가 쓴 글을 너무 맹신하는 것은 위험할 수도 있어요! 같이 학습하면서 누구나 맹신할 수 있을 정도의 글을 같이 작성했으면 좋겠습니다!!
여러분들도 하시다가 좋은 방법이 있다면 바로 알려주시면 너무 좋을 것 같아요
추가 내용
- 제가 위에
response
가undefined
로 오는 경우가 있다고 했는데 그 부분에 대한 내용인 것 같습니다. - 추가적인 의문사항 : 401이나 403에러는 axios interceptor에서 확인하지 못하나요?? 제가 링크 걸었던 깃헙 이슈를 보면
error.response
가 없을 경우 network error라고 하는데... 흠 - 추측 : 403 에러가 발생해서 서버에 접근조차 못하니 당연히 서버로부터 response를 받지 못하므로 undefined 일 것이다? 그럼 개발자 도구에 나타나는 것은...?


개발자도구의 네트워크 탭에선 403 상태코드를 확인할 수 있어요 😇


