import { QueryClient, QueryClientProvider } from "react-query";
import Router from "./shared/Router";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<Router />
</QueryClientProvider>
);
}
export default App;
모든 페이지에서 리액트 쿼리를 사용하기 위해서 최상단(App.js)에서 QueryClientProvider 로 앱을 감싸준다.
쿼리 인스턴스를 생성한다. const queryClient = new QueryClient();
생성한 인스턴스를 넘겨준다. client={queryClient}
GET 요청과 같은 Read 작업을 할 때 사용되는 Hook이다.
첫번째 파라미터로 QueryKey가 들어가고 두번째 파라미터로 비동기 함수(api호출 함수)가 들어간다.
return값은 api의 성공여부, 실패여부, api return값을 포함한 객체이다.
useQuery는 비동기로 작동한다. 즉, 한 컴포넌트에 여러 개의 useQuery가 있다면 하나가 끝나고 다음 useQuery가 실행되는 것이 아닌 두개의 useQuery가 동시에 실행된다. 그러므로 여러개의 비동기 query가 있다면 useQuery보다는 useQueries를 사용하는 것이 좋다.
혹은 Query Options에서 enabled를 사용하면 useQuery를 동기적으로 사용할 수 있다.
import { useQuery } from "react-query";
// 주로 사용되는 3가지 return값 외에도 더 많은 return 값들이 있다.
const { data, isLoading, error } = useQuery(queryKey, queryFn, options)
// 문자열
useQuery('todos', ...)
// 배열
useQuery(['todos', '1'], ...)
❗️쿼리가 변수에 의존하는 경우에는 Query Key에도 해당 변수를 추가해주어야 한다.
const { data, isLoading, error } = useQuery(['todos', id], () => axios.get(`http://.../${id}`));
첫번째 파라미터로 설정한 QueryKey는 다른 컴포넌트에서도 해당 키를 사용하면 호출 가능하다.
const data = useMutation(API 호출 함수, 콜백);
Add 후 수동적으로 Fetch를 해줘야 화면에 보여진다는 불편함이 있다.
이 문제점을 해결하기 위해서는 쿼리 무효화(Invalidation) 를 시켜줘야 한다.
이 전에 캐싱된 쿼리를 직접 무효화 시킨 후 데이터를 새로 패칭해줄 수 있다.
import { useMutation, useQueryClient } from 'react-query';
const AddSuperHero = () => {
✅ const queryClient = useQueryClient();
const addSuperHero = (hero) => {
return axios.post('http://localhost:4000/superheroes', hero);
};
const { mutate: addHero, isLoading, isError, error } = useMutation(addSuperHero, {
onSuccess: () => {
// 캐시가 있는 모든 쿼리 무효화
✅ queryClient.invalidateQueries();
// queryKey가 'super-heroes'로 시작하는 모든 쿼리 무효화
✅ queryClient.invalidateQueries('super-heroes');
}
});
const handleAddHeroClick = () => {
const hero = { 이름, 성별 };
addHero(hero);
};
if (isLoading) {
return <h2>Loading...</h2>;
}
if (isError) {
return <h2>{error.message}</h2>;
}
}