react query 설치
npm install react-query
//index.tsx
import { QueryClient } from "react-query";
import { QueryClientProvider } from "react-query/types/react";
const queryClient = new QueryClient();
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
</QueryClientProvider>
</React.StrictMode>
);
react query를 쓰면 우리 스스로 실행하고 있었던 로직들을 축약해주고, react query를 사용하기 위해 첫 단계로 fetcher 함수를 만들어야 한다. Coins.tsx의 여러줄을 react query를 씀으로써 코드를 간단하게 구현 할 수 있다. (api.tsx)
//api.tsx
export function fetchCoins() {
return fetch("https://api.coinpaprika.com/v1/coins").then((response) =>
response.json()
);
}
useQuery는 2가지 argument를 필요로 하며, 여기서 querykey는 query의 고유 식별자이다.
useQuery(querykey, fetcher function)
isLoading
이라고 불리는 boolean 값을 return 해주는데, 기존의 const [loading,setLoading]을 대체해준다.
추가적으로 강의 내용과 다르게 react 버전이 18이면 타입스크립트에서 react query를 불러오지 못하기 때문에 설치가 필요하고, useQuery를 사용할 때 Query key의 값은 대괄호로 묶어줘야 한다.
npm i @tanstack/react-query
const { isLoading, data } = useQuery<ICoin[]>(["allCoins"], fetchCoins);
이것뿐만이 아니라 코인 하나를 클릭하면 코인에 대한 정보가 보이고, 홈화면 으로 돌아오면 다시 로딩 문구가 보였다. 하지만 이제는 갔다가 다시 돌아와도 더 이상 로딩이 보이지 않는다!
로딩이 보이지 않는 이유는 react query가 데이터를 캐시에 저장해 데이터를 유지하기 때문이다.
시각화 하기 위해서 React query는 Devtools(Developer Tools, 개발자 도구) 라는 것을 가지고 있는데 import 해오면 캐시에 있는 query를 볼 수 있다.
npm i -D @tanstack/react-query-devtools
//App.tsx
import { ReactQueryDevtools } from "react-query/devtools";
function App() {
return (
<>
<GlobalStyle />
<Router />
<ReactQueryDevtools initialIsOpen={true} />
</>
);
}
모든 query는 고유한 key를 가져야하기 때문에 다음과 같이 작성한다.
const {isLoading:infoLoading} = useQuery(["info",coinId], () => fetchCoinInfo(coinId!));
const {isLoading:tickersLoading} = useQuery(["tickers",coinId], () => fetchCoinInfo(coinId!));
!
을 쓰지 않으면 오류가 나는데 !
는 확장 할당 어션셜로 값이 무조건 할당되어있다고 컴파일러에게 전달해 값이 없어도 변수를 사용할 수 있다고 한다.
두 코드 모두 isLoading을 쓰는데, 이름이 같으므로 다르게 지정하면 된다.
📎https://ohlcv-api.nomadcoders.workers.dev/?coinId=btc-bitcoin
강의는 버전5로 진행되어서 React Router v6으로 코드를 수정해보았다.
//Coin.tsx
<Outlet context={{ coinId }} />
//Chart.tsx
interface IProp {
coinId: string;
}
function Chart() {
const { coinId } = useOutletContext<IProp>();
const { isLoading, data } = useQuery(["ohlcv", coinId], () =>
fetchCoinHistory(coinId)
);
return <h1>Chart</h1>;
}
APEXCHARTS
는 자바스크립트 chart library
📎https://apexcharts.com/
npm install --save react-apexcharts apexcharts
자체 api 호출 보내는 경우 time_close가 초단위로 되어있어서 변환해주어야 한다.
categories: data?.map((price) => new Date(Number(price.time_close) * 1000).toISOString())
useQuery hook의 세번째 argument를 알아보자. 첫번째는 고유한 key값, 두번째는 fetcher함수, 세번째는 선택적인 object인데 원한다면 refetch interval을 milliseconds로 할 수 있다.
실시간으로 값이 바뀌는 것을 확인가능🤣
const { isLoading: tickersLoading, data: tickersData } = useQuery<PriceData>(
["tickers", coinId],
() => fetchCoinTickers(coinId),
{
refetchInterval: 5000,
}
);
react helmet 설치 (타입스크립트 쓸 경우 아래 명령어도 쓰기)
npm install react-helmet
npm i --save-dev @types/react-helmet
react-helmet
은 component인데 무엇을 render하던 문서의 head로 간다. 그저 head로 가는 direct link