React-Query는 기존에 프로그래머가 직접 작성해야 했던 비동기 http 통신 로직을 쉽게 다룰 수 있게 해주는 라이브러리이다.
데이터를 항상 최신 상태로 유지해주며, loading, error, success 등 일렬의 컨트롤을 쉽게 할 수 있다.
yarn add react-query 명령어를 사용하여 라이브러리를 설치해준 후
package.json 파일에서 정상적으로 설치가 된 것을 확인해준다.
이후 Context로 하위 컴포넌트를 감싼 후 queryClient를 내려보내 준다.
queryClient는 비동기 요청을 알아서 처리하게 해주는 Background가 된다.
쿼리는 4가지의 상태를 가진다.
1. fresh: 새롭게 추가된 쿼리 인스턴스이며, active 상태의 시작이다. staleTimedl 0이기 때문에 아무런 설정을 해주지 않으면 호출이 끝나고 바로 stale상태로 변한다.
2.fetching: 요청을 수행하는 중인 쿼리이다.
3: stale: 인스턴스가 존재하지만 이미 패칭이 완료된 쿼리이다. 특정 쿼리가 stale된 상태에서 같은 쿼리 마운트를 시도한다면 캐싱된 데이터를 반환하면서 리패칭을 시도한다.
4. inactive: active 인스턴스가 하나도 없는 쿼리이다. inactive된 이후에도 cacheTime동안 캐시된 데이터가 유지되며 cacheTime이 지나면 GC된다.
- *어떻게 inactive가 되는가? : pagenation 관련한 예제를 보니, 페이지네이션을 할 때마다 컴포넌트가 재랜더링 되면서 새로운 쿼리가 만들어지고, 저번 랜더링에서 호출했던 쿼리들은 inactive된다. 렌더링간에 다시 호출되지 않고 언마운트되는 쿼리들은 inactive가 되는 듯 보인다.
출처:https://maxkim-j.github.io/posts/react-query-preview
위와 같이 쿼리문을 작성 해보았다.
- 쿼리는 server state를 요청하는 프로미스를 리턴하는 함수와 함께 unique key로 맵핑된다.
- 쿼리는 콜백 함수의 요청이 프로미스를 리턴한다면 일단 잘 작동한다. 하지만 서버의 데이터를 바꿀 수 있는 요청이라면 mutation 쓰는게 더 추천된다.(이유는 아래 mutation 부분에서 다시 설명)
- useQuery훅의 인자로 2개가 들어감 - 쿼리의 unique한 key, 프로미스를 리턴하는 함수(이 함수는 반드시 resolve Promise를 리턴하거나 에러를 throw해야 한다.)
- unique key : 한 번 fresh가 되었다면 계속 추적이 가능하다. 리패칭, 캐싱, 공유 등을 할때 참조되는 값. 주로 배열을 사용하고, 배열의 요소로 쿼리의 이름을 나타내는 문자열과 프로미스를 리턴하는 함수의 인자로 쓰이는 값을 넣는다.
- useQuery 반환값 : 객체, 요청의 상태를 나타내는 몇가지 프로퍼티, 요청의 결과나 에러값을 갖는 프로퍼티도 포함함
- isLoading, isError, isSuccess, isIdle, status
- error, data, isFetching ⇒ 런타임간 무조건 요청이 한 번 이상 발생했다면 값이 존재한다.
- 쿼리 요청 함수의 상태를 표현하는 status값은 4가지다. status 프로퍼티에서는 문자열로, 상태 이름 앞에 is를 붙인 프로퍼티에서는 불리언으로 해당 상태인지 아닌지를 평가 가능하다.
- idle : 쿼리 data가 하나도 없고 비었을 때. {enabled : false} 상태로 쿼리가 호출되었을 때 이 상태로 시작된다.
- loading : 말그대로 로딩중일 때
- error : 말그대로 에러 발생했을 때
- success : 말그대로 요청 성공했을 때
- 주요 쿼리 옵션
- enabled : 이걸 True로 설정하면 자동으로 쿼리의 요청 함수가 호출되는 일이 없다
- keepPreviousData : success와 loading 사이 널뛰기 방지
- placeholderData : mock 데이터 설정도 가능. 얘는 근데 캐싱이 안됨
- initialData : 초기값 설정
- retry
- 쿼리에 여러가지 옵션 설정을 통해 입맛대로 데이터를 관리할 수 있다
1초의 Loading... 문구 뒤에 데이터가 찍히는 것을 확인할 수 있었다.
- 다음 4가지 경우에 리패칭이 일어난다
- 런타임에 stale인 특정 쿼리 인스턴스가 다시 만들어졌을 때
- window가 다시 포커스가 되었을때(옵션으로 끄고 키는게 가능)
- 네트워크가 다시 연결되었을 때(옵션으로 끄고 키는게 가능)
- refetch interval이 있을때 : 요청 실패한 쿼리는 디폴트로 3번 더 백그라운드단에서 요청하며, retry, retryDelay 옵션으로 간격과 횟수를 커스텀 가능하다.
잘못 된 API주소로 요청을 했을 때 3번 더 요청을 했으며, 다른 브라우저를 클릭하여 포커스를 옮긴 후 실행중인 리액트 앱을 다시 클릭해서 포커스가 됐을 때 리패칭이 일어났다.
쿼리 키를 배열로 준 후 파라미터를 주어 id값 등 구분자로 이용할 수도 있다.
useMutation
위와 같이 mutaion hook을 짜주었다.
버튼을 클릭 할 시에 새로운 데이터를 POST한다.
데이터가 잘 추가된 것을 확인할 수 있었다. console로 useMutation의 onSeccess함수가 받는 매개변수도 출력해보았다. variables는 전송한 객체이며, context는 onMutate에서 return한 값이다. 이 때 쿼리무효화를 해주지 않으면 서버의 데이터가 변경 된 후에 리패칭이 되지 않아 윈도우에 다시 포커스가 됐을 때 useQuery의 규칙에 따라 리패칭이 되었다.
쿼리 무효화를 명시해주면 쿼리키를 참조하여 자동으로 리패칭을 시도하고 추가된 데이터가 view에 나타난다.
+ useMutation의 경우, CUD에 해당하는 API 콜 후, 서버의 response를 data에서 받아올 수 없다. 성공/실패 여부는 알 수 있다!
'React.js' 카테고리의 다른 글
[React] DOM에 컴포넌트를 빠르게 나타내기 위해 .. (0) | 2022.01.24 |
---|---|
[React] React-Query 쿼리무효화, queryClient.invalidateQueries() (0) | 2022.01.20 |
[React] Cannot read properties of undefined... Error (0) | 2022.01.19 |
[React] json-server 사용하기 (0) | 2022.01.19 |
[React] [object Object] Issue (0) | 2022.01.18 |