React 애플리케이션에서 서버 state를 fetching, caching, synchronizing, updating할 수 있도록 도와주는 라이브러리,
리액트에서 비동기 로직을 리액트스럽게 다룰 수 있게 해주는 라이브러리이다.
"global state"를 건드리지 않고 React 및 React Native 애플리케이션에서 데이터를 가져오고, 캐시하고, 업데이트한다.
npm i @tanstack/react-query
별도로 모듈을 설치해야하고,const { isLoading, data } = useQuery(["allCoins"], fetchCoins);
- index.tsx
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
root.render(
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
</QueryClientProvider>
);
const queryClient = new QueryClient();
선언QueryClientProvider
를 최상단에서 감싸주어야한다.QueryClientProvider
는 client
prop 을 필요로하며,queryClient
을 넣어주면 완료.useState
와 useEffect
를 모두 주석처리해주었다. 물론 useEffect
안에 있는 fetch
도 같이fetch
함수를 'api.ts' 파일에 만들어주었다- api.ts
export function fetchCoins() {
return fetch("https://api.coinpaprika.com/v1/coins")
.then((response) => response.json());
}
async , await
을 사용해도 되지만, 니코는 코드가 깨끗(?) 하기를 원해서 .then()
을 사용함fetchCoins
은 URL 을 부르고(API를 fetch 하고)useQuery() 의 첫번째 파라미터로 unique Key가 들어가고,
두번째 파라미터로 비동기 함수(api호출 함수)가 들어간다.
(두번째 파라미터는 promise 를 반환해야함)
- `Coins.tsx`
function Coins() {
const { isLoading, data } = useQuery(["allCoins"], fetchCoins);
isLoading
: true 혹은 fasle 인 boolean 값을 return 하는데,
전에 사용했던 const [ loading, setLoading ] = useState(true);
을 대체한다.
fetchCoins
함수가 loading 중이라면isLoading
이 booelan 값을 통해 아직 loading 중임을 표시해주고fetchCoins
함수의 loading 이 끝났다면, isLoading
이 loading 이 끝났음을 알려줄 것이다.data
: fetchCoins
함수가 모두 완료되면, react query 가 함수의 데이터를 해당 data
에 넣어준다.
즉, useQuery hook 이 fethcer 함수를 부르고, loading 중인지 확인도 해주고, 불러온 값(json)을 data 에 넣어주기까지 할거다.
만약 console.log(isLoading, data)를 찍어본다면, 결과는 아래와 같다
로딩 중일 때 isLoading : true
, data : undefined
로딩이 끝나면, isLoading : false
, data : object...
따라서, loading
state 는 isLoading
으로,
coins
state는 data
으로 바뀐다.
그러나 typescript 는 data 가 뭔지 모르니, coin 도 모른다.
interface ICoin {
id: string;
name: string;
symbol: string;
rank: number;
is_new: boolean;
is_active: boolean;
type: string;
}
function Coins() {
const { isLoading, data } = useQuery<ICoin[]>(["allCoins"], fetchCoins);
...
이전 state 에서 사용했던걸 그대로 가져오면된다!
마지막으로, 'Coin' 페이지(detail)에서 'Coins' 페이지(main)로 이동할때 더이상 loading 이 보이지 않을 것이다.
그 이유는 react query 가 Coins()
의 response 를 caching 하고 있기 때문.
그래서 우리가 화면을 바꿨다가 돌아오더라도 React Query 는 우리가 원하는 data가 이미 캐시(cache)에 있다는 것을 알고,
API 에 접근하지 않고 캐시에 있는 data를 주기 때문에 loading 이 뜨지 않는 것..