React
리액트 쿼리 다시 배우기 (1)</br> 참고자료
React-Query
- 리덕스에서 리액트 쿼리를 리팩토링하며 쿼리로 받아온 데이터를 재사용해야 되는 경우가 생겼다.
- 쿼리로 받아온 데이터는 캐시된 데이터로 별도의 재요청 없이도 데이터를 사용할 수 있는 건 알지만, 내가 원하는 건
A라는 데이터에서 B라는 데이터로 갔다가 다시 A라는 데이터를 활용하는 것이었다.- 어차피
key로 저장된 데이터이기 때문에, 내가 사용할 key값만 알고 있다면 그 데이터를 다시 꺼내서 사용할 수 없을까?
쿼리의 다양한 메서드
- 우리는 하위 컴포넌트에서 쿼리를 사용할 수 있도록, 최상위 컴포넌트에
queryClient를 생성하여 사용하고 있다. - 우리가 사용하는 쿼리의 데이터는
queryClient에 저장되며 활용할 수 있는 여러가지 메서드가 존재한다.
fetchQuery, prefetchQuery
fetchQuery 데이터 혹은 에러를 반환하는 비동기 메서드이다.setQueryData와 달리 데이터를 가져오는 동안 동일한 쿼리에 대한 useQuery인스턴스를 사용하여 중복 요청이 생기지 않도록 한다.
prefetchQuery 반환값 없이 데이터를 fetch하기 위한 용도로만 사용되는 메서드이다.
getQueryData
- 키 값만 알고 있다면, 캐시된 데이터를 얻을 수 있다.
- 예를 들어 아래의 코드에서,
index.tsx에서 넘겨주고 있는 queryClient 다른 컴포넌트에서 활요할 수 있다. App.tsx라는 컴포넌트에서 react라는 문자열로 데이터를 받아오고 있다고 가정하자.- 단순히 가져온 쿼리 데이터를 활용해야하는 상황이 있다면, 우리는 이 데이터를 다른 컴포넌트에서 보여주기 위해 또 다시
api요청을 하지 않고 getQueryData를 사용하여 키에 해당하는 데이터를 불러올 수 있다.
1
2
3
4
5
6
| // getQueryData 형태
{
config: ...,
data: [{...}, {...} , ...],
headers: ...
}
|
// index.tsx
import React from "react";
import ReactDOM from "react-dom";
import "./style/index.css";
import App from "./App";
import { QueryClient, QueryClientProvider } from "react-query";
export const queryClient = new QueryClient();
ReactDOM.render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>,
document.getElementById("root")
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // App.tsx
import { useQuery } from "react-query";
const useFetchData = (stack: string) => {
const { data } = useQuery([stack], () => axios.get("/stack"));
return data;
};
const App = () => {
const data = useFetchData("react");
return <div>{data}</div>;
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| // UseQueryData.tsx
const UseQueryData = () => {
const recycleData = queryClient.getQueryData("react");
// App 컴포넌트에서 받아온 데이터 키 값인 react
return (
<div>
{recycleData.map((data) => (
<span>{data.data.title}</span>
))}
</div>
);
};
|
getQueryCache
refetchQueries
- 특정 조건에서 쿼리들을
refetch하고 싶을 때 사용한다.
1
2
3
4
5
6
7
8
| // 모든 쿼리 리패치
await queryClient.refetchQueries();
// stale이 true인 쿼리 리패치
await queryClient.refetchQueries({ stale: true });
// 쿼리 키가 "post"로 시작하고 active가 true인 쿼리 리패치
await queryClient.refetchQueries(["posts", { active: true }]);
|
cancleQueries
- 쿼리 요청을 수동으로 취소할 수 있다.
- 예를 들어, 서버 요청이 오래 걸려 사용자가 직접 요청을 취소할 수 있는 버튼을 만들어 쿼리를 취소하고 이전 상태로 되돌릴 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| const App = () => {
const exampleQuery = useQuery(queryKey, queryFn);
return (
<button
onClick={(e) => {
e.preventDefault();
queryClient.cancleQueries(queryKey);
}}
>
Cancle
</button>
);
};
|
removeQueries, clear
1
2
3
4
5
| // example로 시작하는 쿼리 제거
queryClient.removeQueries(["example"]);
// 모든 쿼리 제거
queryClient.cliear();
|
resetQueries
참고자료</br>
- 초깃값으로 쿼리들을 초기화할 때 사용한다.
clear, remove는 캐싱된 쿼리 데이터를 제거하는 역할만하기 때문에, 사용자가 이를 알아차릴 수 없다.- 반면,
resetQueries는 캐싱된 쿼리 데이터를 제거함과 동시에 초깃값이 있다면 초깃값으로 데이터를 보여주고, 데이터를 다시 받아오기 때문에 isFetching, isLoading 등의 상태를 사용자가 알 수 있다.
setDefaultOptions, getDefaultOptions
- 쿼리의 기본 옵션을 확인하고 설정하는 역할을 한다.
- 기존에 작성된 옵션을 덮어씌운다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| const queryClient = new QueryClient({
defaultOptions:{
staleTime: 100,
}
});
queryClient.setDefaultOptions({
queries: {
staleTime: 600;
}
})
queryClient.getDefaultOptions();
// staleTime : 600
|
이 외에도 다양한 메서드들이 존재하니 공식문서를 여러 번 살펴보자