React Query 란 서버 상태를 관리하는 라이브러리이다.
useQuery는 React Query를 이용해 서버로부터 데이터를 조회해올 때 사용한다.
useQuery를 사용하기 위해서는 두가지 개념이 필요하다
// 1
const res = useQuery(queryKey, queryFn);
// 2
const res = useQuery({
queryKey: queryKey,
queryFn: queryFn
});
이런 모양으로 사용하게 된다.
useQuery마다 부여되는 고유 Key 값이다.
문자열로 사용될수도 있으며 배열 형태로도 사용할수가 있다.
문자 뿐만 아니라 배열에 입력 순서가 보장되기 때문에 순서는 중요하게 생각해야 한다.
const res = useQuery(['persons', 'add Id'], queryFn);
const res = useQuery(['add Id', 'persons'], queryFn);
위와 아래 함수는 동일하지 않다.
queryKey의 역할은 React Query가 query 캐싱을 관리할 수 있도록 도와준다.
캐싱을 통해서 같은 함수가 반복되더라도 고유 queryKey 값이 같으면 api 호출은 한번일어나고 일어난 결과값을 캐싱해서 사용한다.
const getPersons1 = () => {
const res1 = useQuery(['persons'], queryFn1);
}
const getPersons2 = () => {
const res2 = useQuery(['persons'], queryFn2);
}
위 함수 두개를 실행하면 키값이 같기때문에 호출은 한번 일어나고 캐싱되어진 값을 불러서 사용된다.
promise 처리가 이루어지는 함수이다.
여기서 api 호출을 할수 있다.
// 1
const res = useQuery(['persons'], () => axios.get('http://localhost:8080/persons'));
// 2
const res = useQuery({
queryKey: ['persons'],
queryFn: () => axios.get('http://localhost:8080/persons')
});
cacheTime은 말 그대로 캐싱 처리가 이루어지는 시간을 의미한다.
cacheTime은 default값으로 5분으로 설정되어 있다.
5분 이내에서는 캐시를 이용해서 데이터를 가져온다.
Stale 은 탁한, 신선하지 않은 뜻을 가지고 있는데 한번 데이터를 조회해오면 해당 데이터는 탁해진다(stale)그래서 계속 refetch가 발생이 되서 계속 호출 한다.
디폴트 값은 0초이다.
useQuery에는 staleTime, cacheTime 두 개념이 모두 존재하기 때문에 둘 중 하나라도 만족되지 않으면 서버에 다시 데이터를 요청하게 된다.
세번째 파라미터가 옵션인데 세번째 파라미터 값에 객체 형태로 넣어주면 된다. 객체로 사용했을때는 키와 벨류 값으로 그냥 사용하면 된다. ms단위 이기 때문에 1000=1초 이다.
// 1
const res = useQuery(['persons'], () => axios.get('http://localhost:8080/persons'), {
staleTime: 5000, // 5초
cacheTime: Infinity, // 제한 없음
});
// 2
const res = useQuery({
queryKey: ['persons'],
queryFn: () => axios.get('http://localhost:8080/persons'),
staleTime: 5000, // 5초
cacheTime: Infinity // 제한 없음
});
useQuery는 윈도우 창 전환만으로도 계속 호출한다. window focus Default값이 true이기 때문이다.
자주 업데이트가 필요 없기 때문에 불필요한 호출이라고 생각되어 꺼놓고 사용하게 된다.
설정 방법은 전역적, 개별 로 나뉜다.
app.js란에 queryClient값을 설정해두었는데 그 값의 옵션을 조절해주면 된다.
import * as React from 'react';
import ReactDom from 'react-dom';
import { QueryClient, QueryClientProvider } from 'react-query';
import App from './App';
const queryClient = new QueryClient(
{
defaultOptions: {
queries: {
refetchOnWindowFocus: false, // window focus 설정
}
}
}
); // queryClient 생성
ReactDom.render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>,
document.querySelector('#root')
);
호출하는 옵션 (세번째 매개변수)에서 조절해주면 된다.
// 1
const res = useQuery(['persons'], () => axios.get('http://localhost:8080/persons'), {
refetchOnWindowFocus: false});
// 2
const res = useQuery({
queryKey: ['persons'],
queryFn: () => axios.get('http://localhost:8080/persons'),
refetchOnWindowFocus: false});
조건이 맞을 경우 데이터 요청을하고 아닐 경우 요청을 하지 않도록 설정이 가능하다.
Enabled 값을 이용해서 조건을 설정해줄수가 있다. 아래 예시는 params값으로 id를 넘겨주는데 id값이 없으면 호출이 실행되지 않도록 코드가 구현되어 있다. enabled의 default값은 true로 되어 있다.
// 1
const res = useQuery(['person', id], () => axios.get('http://localhost:8080/person', {
params: {
id: id,
}
}), {
enabled: !!id // 코드 자동 실행 설정
});
// 2
const res1 = useQuery({
queryKey: ['person', id],
queryFn: () => axios.get('http://localhost:8080/person', {
params: {
id: id,
}
}),
enabled: !!id // 코드 자동 실행 설정
});
만약 여러번 호출 해야 할경우는 어떻게 해야 할까
useQuery를 여러번 사용해도 되지만 useQueries를 제공한다.
useQueries는 promise.all()처럼 query함수들을 모아서 한번에 작성이 가능하다.
useQueries([
{ queryKey: ["post", 1], queryFn: getPost },
{ queryKey: ["post", 2], queryFn: getPost },
{ queryKey: ["post", 3], queryFn: getPost },
]);
예시와 내용은 J4J님이 작성해두신 글에서 공부하고 정리를 하였습니다.
https://jforj.tistory.com/243
다음번에는 useInfinityQuery에 대해 알아 보도록 하자.