- 서버와 API를 통신하면서 가져오는 값들에 대해 Update / Caching / Error-Handling 등 비동기 통신 과정에서 다양한 처리를 진행할 수 있습니다.
- 기본적으로 서버 상태를 관리해주는 라이브러리입니다.
- 컴포넌트는 렌더링만 집중할 수 있도록 도와줍니다.
- 지원 기능
- Caching 기능 제공
- 일반적으로 5분 후에 가비지 컬렉터가 수거합니다!
chacheTime
으로 조절 가능
- Get을 통해 불러온 데이터가 Update 되었을 때 자동 갱신 ( Get을 다시 요청 )
- 오래된 데이터 최신화 ( Get 다시 요청 )
- 중복 Get 요청을 한번만 요청 ( 옵션으로 조정 가능 )
- 무한 스크롤 지원
- React Hook과 비슷하여 사용 편리
- 친절한 공식문서
- React Query에서 관리하는 기본적인 Data의 상태 ( 중요 )
종류 | 설명 |
---|
fetching | 요청중인 Query |
fresh | 만료되지 않는 최신의 데이터, 컴포넌트가 마운트 / 업데이트가 발생해도 데이터를 다시 재요청 하지 않음 |
stale | 만료된 과거의 데이터, 일정 시간이 지나면 가비지 컬렉터가 수거 |
inactive | 사용하지 않는 Query로 일정 시간이 지나면 가비지 컬렉터가 캐시에서 제거 |
delete | 가비지 컬렉터가 캐시에서 제거한 Query |
- React Query의 기본 default 설정
useQuery
로 가져온 데이터는 기본적으로 stale
상태
stale
상태의 Query들은 아래의 4가지 경우 백그라운드에서 refetching
( 서버로 부터 재요청 ) 실행
- 새로운 쿼리 인스턴스가 마운트
- 브라우저 윈도우가 다시 포커스
- 네트워크 재연결
refetchInterval
옵션 활성화
- 모든 Query의 Data는 캐싱이 이루어짐
- 해당 Date는
inactive
상태가 되고 일반적으로 5분 후에 가비지 컬렉터가 수거
- 백그라운드에서 3번 쿼리 요청 실패시 에러 처리
- Query의 결과로 만들어진
stale
한 데이터는 업데이트 전까지 보전
- Query 결과는 데이터가 변경되지 않은 경우 참조가 변경되지 않고 유지
2. 설치 및 셋팅
yarn add react-query
import React from "react";
import App from "./App";
import { createRoot } from "react-dom/client";
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
const container = document.getElementById("root");
const root = createRoot(container);
const queryClient = new QueryClient();
root.render(
<QueryClientProvider client={queryClient}>
{}
<ReactQueryDevtools initialIsOpen={true} />
<App />
</QueryClientProvider>
);
3. useQuery
- 서버로부터 데이터를 Get 하기 위한 API 입니다.
- 파라미터
- 첫번째: unique Key ( 다른 컴포넌트에서도 해당 키로 동일한 호출 가능 )
- String
- Array: [ unique Key, value ]
- 쿼리가 변수에 의존하는 경우에는 QueryKey 에도 해당 변수를 추가해주어야한다.
- value 값은 useQuery 함수 내부의 파라미터로 값이 전달 됩니다.
useQuery(['key', id], () => axios.get(http://.../${id}))
;
- 두번째: API 호출하는 비동기 함수 ( Promise )
- 세번째: options
- Return
- api의 로딩중 / 성공 / 실패 여부
- api의 return value 값을 포함한 객체
- 실패시 error 객체
- 비동기로 작동
- 컴포넌트 한개에 여러개의 useQuery가 존재할 경우 동시에 실행됩니다.
useQuery
를 다중으로 사용할 경우 useQueries
사용
- 동기로 작동하기 위해서는
enabled
사용
- 소스코드
- 기본적으로 다른 컴포넌트에서도 Key가 동일할 경우 1번만 요청하며 그 다음부터는 캐싱된 데이터를 불러옵니다.
- 브라우저 탭을 변경하거나 해당 화면 포커싱이 될 때마다 새로운 Get 요청을 통해 데이터를 다시 불러옵니다.
refetchOnWindowFocus
옵션으로 설정 가능
- 또한 Get 요청이 실패할 경우 지속적으로 몇번 호출하다가 나중에
isError = true
값으로 바뀌면서 error 객체를 리턴합니다.
import React from "react";
import axios from "axios";
import { useQuery } from "react-query";
import "./App.css";
function App() {
const fetchList = () => {
return axios(`https://jsonplaceholder.typicode.com/posts/1`);
};
const { status, isLoading, isSuccess, isError, data, error } = useQuery(
"key",
fetchList
);
return <div>Hello World</div>;
}
export default App;
import React from "react";
import axios from "axios";
import { useQuery } from "react-query";
import "./App.css";
function App() {
const fetchList = () => {
return axios(`https://jsonplaceholder.typicode.com/posts/1`);
};
const { status, isLoading, isSuccess, isError, data, error } = useQuery(
"key",
fetchList
);
console.log(status);
if (isLoading) {
return <span>Loading</span>;
}
if (isError) {
return <span>{error.message}</span>;
}
return <div>{data.data.title}</div>;
}
export default App;
4. Options ( 더 자세한건 공식문서 참조 )
refetchOnWindowFocus
: boolean
- 데이터가 stale 상태일 때 윈도우가 포커싱 될 때마다 refetch를 실행합니다. ( 기본값: true )
- 예시) 크롬에서 다른 탭을 눌렀다가 다시 원래의 탭을 돌아온 경우
- stale: 최신이 아닌 데이터, React Query는 캐시되 데이터를
stale
하다고 정의
- refetch: 서버로 부터 데이터를 불러오는 과정
refetchOnWindowFocus: always
: 항상 윈도우 포커싱 될 때 refetch 진행
retry
: number / boolean
- 실패한 쿼리에 대한 재시도를 설정하는 옵션
- 기본적으로 3번 재시도
true
일 경우 무한 재시도 / false
일 경우 재시도를 하지 않습니다.
enabled
: boolean
- React Query가 자동으로 실행되지 않게 설정하는 옵션입니다.
- 원래 해당 페이지가 렌더링 되면서
useQuery()
가 존재할 경우 자동으로 서버로 데이터 요청
true
일 경우 요청하지 않고 / false
일 경우 요청합니다.
- 보통 특정 변수를 활용해서 그 변수의 값이 들어올 경우 요청하도록 설정할 때 사용
import React, { useState } from "react";
import axios from "axios";
import { useQuery } from "react-query";
import "./App.css";
function App() {
const fetchList = () => {
return axios(`https://jsonplaceholder.typicode.com/posts/1`);
};
const [id, setId] = useState("");
setTimeout(() => {
setId(3);
}, 2000);
const { status, isLoading, isSuccess, isError, data, error } = useQuery(
["key", id],
fetchList,
{
enabled: !!id,
refetchOnWindowFocus: false,
retry: 0,
}
);
console.log(status);
if (isLoading) {
return <span>Loading</span>;
}
if (isError) {
return <span>{error.message}</span>;
}
return <div>{data && data.data.title}</div>;
}
export default App;
staleTime
: number / Infinity
- 데이터의
fresh
상태를 유지하는 시간으로 해당 시간이 지나면 stale
상태가 됩니다. ( 기본적으로 0 )
fresh
: 최신 상태의 데이터
fresh
상태일 때는 쿼리가 다시 mount되어도 fetch가 실행되지 않음
stale
: 최신 상태가 아닌 데이터
cacheTime
: number / Infinity
inactive
상태인 캐시 데이터가 메모리에 남아있는 시간입니다. ( 기본 5분으로 설정 )
inactive
: 사용하지 않는 쿼리, 일정 시간이 지나면 가비지 컬렉터가 캐시에서 제거
- 해당 시간이 지나면 가비지 컬렉터에 의해 메모리에서 제거됩니다.
refetchOnMount
: booelan / always
- 데이터가
stale
상태일 경우 마운트 될 때마다 refaetch
를 실행하는 옵션입니다. ( 기본적으로 true
)
- always 설정시 마운트 할 때마다
retetch
refetchOnReconnect
: boolean / always
- 데이터가
stale
상태일 경우 네트워크 연결이 다시 이루어질 때 retetch
를 실행하는 옵션입니다. ( 기본적으로 true
)
- always 설정시 계속 재 연결될 때
retetch
실행
onSuccess
: (data) => void
- Query가 성공할 때 실행되는 함수입니다.
- 파라미터로 data를 받을 수 있으며 성공할 때 서버에서 넘어오는 Response 입니다.
onError
: (error) => void
- Query가 실패할 때 실행되는 함수입니다.
- 파라미터로 error를 받을 수 있으며 서버에서 요청이 실패할 때 받을 수 있는 Response 입니다.
onSettled
: (data, error) => void
onSuccess
와 onError
를 혼용으로 사용할 수 있는 옵션이며 API 요청의 성공 / 실패에 따라 자동으로 파라미터가 전달되는 함수 입니다.
initialData
: data / () => data
- Query가 아직 생성되지 않거나 캐시되지 않았을 때 Query 캐시 데이터의 초기 데이터를 설정할 수 있습니다.
staleTime
이 설정되지 않았다면 초기 데이터도 기본적으로 stale
상태로 취급
5. 참고