#5.9-11. React Query

Jisoo Shin·2023년 10월 12일
0

ReactJs마스터클래스

목록 보기
12/17
post-custom-banner

본 포스팅은 노마드 코더의 React JS 마스터클래스를 수강한 뒤 작성되었습니다.

React Query

<참고 문헌 - React Query 한글 메뉴얼>
https://velog.io/@familyman80/React-Query-%ED%95%9C%EA%B8%80-%EB%A9%94%EB%89%B4%EC%96%BC

기존 방식 (우리가 전에 데이터를 받아온)

  const [loading, setLoading] = useState(true);
  const [info, setInfo] = useState<InfoData>();
  const [priceInfo, setPriceInfo] = useState<PriceData>();

 useEffect(() => {
    (async () => {
      const infoData = await (
        await fetch(`https://api.coinpaprika.com/v1/coins/${coinId}`)
      ).json();
      console.log(infoData);

      const priceData = await (
        await fetch(`https://api.coinpaprika.com/v1/tickers/${coinId}`)
      ).json();
      console.log(priceData);

      setInfo(infoData);
      setPriceInfo(priceData);
      setLoading(false);
    })();
  }, [coinId]);

BUT!! 우리는 이제 이렇게 할 필요가 X.
위에 有는 코드들을 다 삭제해도 됨.


📌 React Query에 대해서

npm i react-query

❗ 아래에 작성되는 모든 것들은 index.tsx에서 진행됨. (react query를 사용하기 위한 install이라고 생각하면 됨)

(1) queryClient 만들기

const queryClient = new QueryClient()

(2) provider 만들기
- 우리가 themeProvider에서 했던 것과 비슷
- QueryClientProvider안에 있는 모든 것은 queryClient에 접근 가능!

return (
  <QueryClientProvider client={queryClient}>
  	<Todos />
  </QueryClientProvider>
index.tsx 전체 코드
import React from "react";
import ReactDOM from "react-dom";
import { ThemeProvider } from "styled-components";
import App from "./App";
import { theme } from "./theme";
import { QueryClient, QueryClientProvider } from "react-query";

const queryClient = new QueryClient();

ReactDOM.render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <ThemeProvider theme={theme}>
        <App />
      </ThemeProvider>
    </QueryClientProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

📌 React Query의 기능

  • 우리가 우리 스스로 실행하고 있었던 로직들을 축약해줌.

📌 React Query를 사용하기 위한 방법

1. fetcher 함수 만들기 (fetch를 하는 함수들)

  • api.tsx라는 파일 만들기
    - 해당 파일 안에다가 이제 fetcher 함수들을 만듬
    - fetcher 함수는 꼭 fetch promise를 return 해줘야함. (json data를 return)
export async function fetchCoin() {
  return fetch("내가 원하는 url").then(response => response.json()
  );
}

-> 이처럼 우리는 현재 api.tsx라는 타 파일 생성 후, API를 fetch하고 json을 return하는 함수를 만들었음.


2. useQuery를 사용해서 우리가 만들어둔 fetcher 함수 가져오기

const { isLoading, data } = useQuery("allCoins", fetchCoins)

-> useQuery는 fetchCoins 함수를 부르고, 해당 함수가 loading 중이라면 isLoading을 통해 알려줌.
-> fetchCoins 함수가 끝난다면, 해당 함수가 return하는 json 값을 data에 넣음.

∴ 우리가 작업하는 화면 상에서는 위의 한줄로 모든 것을 끝낼 수 있는 것.


api.tsx 전체 코드
export function fetchCoins() {
  return fetch("https://api.coinpaprika.com/v1/coins").then((response) =>
    response.json()
  );
}

바뀐 Coins.tsx 전체 코드
import { Link } from "react-router-dom";
import styled from "styled-components";
import { useQuery } from "react-query";
import { fetchCoins } from "./api";

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);

  return (
    <Container>
      <Header>
        <Title>코인</Title>
      </Header>
      {isLoading ? (
        <Loader>Loading...</Loader>
      ) : (
        <CoinsList>
          {data?.slice(0, 100).map((coin) => (
            <Coin key={coin.id}>
              <Link
                to={{
                  pathname: `/${coin.id}`,
                  state: { name: coin.name },
                }}
              >
                <Img
                  src={`https://coinicons-api.vercel.app/api/icon/${coin.symbol.toLocaleLowerCase()}`}
                />
                {coin.name} &rarr;
              </Link>
            </Coin>
          ))}
        </CoinsList>
      )}
    </Container>
  );
}

const Container = styled.div`
  padding: 0px 20px;
  max-width: 480px;
  margin: 0 auto;
`;

const Header = styled.header`
  height: 10vh;
  display: flex;
  justify-content: center;
  align-items: center;
`;

const CoinsList = styled.ul``;

const Coin = styled.li`
  background-color: white;
  color: ${(props) => props.theme.bgColor};
  padding: 20px;
  border-radius: 15px;
  margin-bottom: 10px;
  a {
    display: flex;
    align-items: center;
    padding: 20px;
    transition: color 0.2s ease-in;
  }
  &:hover {
    a {
      color: ${(props) => props.theme.accentColor};
    }
  }
`;

const Title = styled.h1`
  font-size: 48px;
  color: ${(props) => props.theme.accentColor};
`;

const Loader = styled.span`
  text-align: center;
  display: block;
`;

const Img = styled.img`
  width: 35px;
  height: 35px;
  margin-right: 10px;
`;


export default Coins;

📌 React Query DevTools

Reqct Query를 통해서 API로부터 data를 받아온 경우, 자동적으로 cache에 해당 data들이 저장되어 有

-> 해당 저장된 것을 볼 수 있게 개발자를 위한 도구를 제공하는데 그것이 바로 react query devtools이다.

1. App.tsx 추가

import { ReactQueryDevtools } from "react-query/devtools";
  
  ...
  
function App() {
  return (
    <>
      <GlobalStyle />
      <Router />
      <ReactQueryDevtools initialIsOpen={true} />
    </>
  );
}

이런식으로 현재 저장되어 있는 데이터들이 나옴.


📌 하나의 .tsx 에서 2개 이상의 react query 사용 하는 경우 & fetch 함수에 변수 넘겨주기

  //fetch 함수에 변수를 넘겨줘야 하는 경우
  const { isLoading: infoLoading, data: infoData } = useQuery(
    ["info", coinId],
    () => fetchCoinInfo(coinId)
  );
  
  // 2개의 함수에서 동일하게 isLoading, data라는 값을 가지면 X되니까, : 를 사용해서 각자 이름을 지정
  const { isLoading: tickersLOading, data: tickersData } = useQuery(
    ["tickers", coinId],
    () => fetchCoinInfo(coinId)
  );
post-custom-banner

0개의 댓글