React/React Query

React Query 리액트 쿼리 사용법 사용하는 이유

onurmind38 2023. 2. 28. 19:46

 

📌 기존의 코드는 다음과 같다.

 

loading 이라는 값을 통해 데이터가 다 불러와졌는지를 판별한다.

그리고 데이터가 다 불러와졌다면 loading 을 false 값으로 전환하고

데이터를 setCoins 를 통해 coins 에 데이터를 담는다.

 

이러한 과정은 두개의 useState를 사용하게 만드는 단점이 존재한다.

  const [coins, setCoins] = useState<CoinInterface[]>([]);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
     axios
       .get("https://api.coinpaprika.com/v1/tickers")
      .then((Response) => {
       setCoins(Response.data.slice(0, 99));
        setLoading(false);
      })
      .catch((Error) => {
        console.log(Error);
       });
}, [coins]);

 

🌈 React Query 를 통해 쉽게 해결해보자.

 

설치 : npm i @tanstack/react-query 

...(중략)

// 기본 셋팅 방법 
import { QueryClient , QueryClientProvider} from "@tanstack/react-query";

const queryClient = new QueryClient();

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);

root.render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <ThemeProvider theme={darkTheme}>
        <App />
      </ThemeProvider>
    </QueryClientProvider>
  </React.StrictMode>
);

 

아래 코드가 한줄로 변환한 코드이다. (물론 api 를 다른 파일로 저장해두어야한다. => api.ts 파일)

 

Coins.tsx

 const { isLoading , data } = useQuery<CoinInterface[]>(["allCoins"] , getCoins)

api.ts

import axios from "axios";

function getCoins() {
  return axios
    .get("https://api.coinpaprika.com/v1/tickers")
    .then((Response) => {
      return Response.data;
    })
    .catch((Error) => {
      console.log(Error);
    });
}

export default getCoins;

정리해보면 앞선 loading 의 역할을 isLoading 이 대신해준다. 

useQuery 의 getCoins 함수가 끝나면 isLoading 은 false 가 되며 데이터는 data에 담기게 된다.

 

또 한가지 좋은점은 해당 데이터를 ["allCoins"] 라는 캐시에 담아 저장하기 때문에 재호출 하지 않는다.

 

 

📌 coin.tsx : refetchInterval : 2000 을 이용하면 지정한 시간마다 getCoinPrice 함수를 refetching 한다.

const { isLoading: priceLoading, data: priceData } = useQuery<PriceData>(
    ["PriceInfo", coinId],
    () => getCoinPrice(`${coinId}`),
    {
      refetchInterval: 2000,
    }
  );