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
|
이 외에도 다양한 메서드들이 존재하니 공식문서를 여러 번 살펴보자