React-Query를 이해하기 위해서

2023. 8. 9. 22:43Trip to React

react-query를 강의에서 배웠지만 한 번 까먹었다. 사실 코드상 어렵지는 않은 데 어색해서 까먹었다. 근데 한 번 까먹으면 두 번 까먹기 쉬우므로 기록을 남긴다. 그리고 카카오도 쓰니 중요한 라이브러리 인 것 같다.

 

import React from "react";
import ReactDOM from "react-dom/client";
import { QueryClient, QueryClientProvider } from "react-query";
import { ThemeProvider } from "styled-components";
import App from "./App";
import { RecoilRoot } from "recoil";

const queryClient = new QueryClient();

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <RecoilRoot>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </RecoilRoot>
);

 

기본적으로 세팅을 해줘야한다. 다음으로,

 

  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();
      const priceData = await (await fetch(`https://api.coinpaprika.com/v1/tickers/${coinId}`)).json();
      setInfo(infoData);
      setPriceInfo(priceData);
      setLoading(false);
    })();
  }, [coinId]);

노마드 코더에서 배운 예제 코드이다. 유즈 스테이트로 상태를 보고 effect로 데이터를 불러온다. 그리고 mappiing을 할 것이다. 우리는 통상 이런 코드를 많이 쓴다. 프로젝트가 커지면 상태 관리 프로그램으로 관리한다고들 한다. 사실 나는 리액트 초보라 Redux를 잘 모르는데 react-query를 이야기하면 나오는 이야기이다. 

 

여튼 코드는 api를 통해 데이트를 받아 각 상태에 뿌려준다. 하지만, 리액트 쿼리를 통해서 보다 깔끔하게 정리해 줄 수 있다.

 

const BASE_URL = `https://api.coinpaprika.com/v1`

export function fetchCoins () {
  return fetch(`${BASE_URL}/coins`).then(response => response.json());
};

export function fetchCoinInfo(coinId: string) {
  return fetch(`${BASE_URL}/coins/${coinId}`).then(response => response.json());
};

export function fetchCoinTickers(coinId: string) {
  return fetch(`${BASE_URL}/tickers/${coinId}`).then(response => response.json());
};

export function fetchCoinHistory(coinId: string){
  return fetch(`https://ohlcv-api.nomadcoders.workers.dev?coinId=${coinId}`).then(response => response.json());
}

 

먼저 api.js 파일을 만들어 데이터 받아오는 함수를 빼준다. 

const { isLoading: infoLoading, data: infoData } = useQuery<InfoData>(
    ["info", coinId],
    () => fetchCoinInfo(coinId!)
  );

그리고 유즈쿼리를 통해서 정리해줄 수 있다. 이즈로딩은 데이터를 받기전 로딩을 보여주는 것이고 데이터는 api로 받은 데이터를 받는 것이다. 꺽쇠괄호에는 쿼리키를 작성할 수 있다. 아래는 쿼리키의 역할을 gpt에게 물어봤다.

 

---

 

React Query에서 쿼리 키(query key)는 캐시된 데이터를 식별하고 관리하는 데 사용되는 중요한 역할을 합니다. 간단히 말해, 쿼리 키는 어떤 종류의 데이터를 가져오는 데 사용되는 식별자입니다.

쿼리 키는 다음과 같은 방법으로 정의됩니다:

문자열 키: 가장 일반적으로 사용되는 형태로, 데이터의 유형을 식별하기 위해 문자열로 표현됩니다. 예를 들어, "todos"라는 쿼리 키는 할 일 목록을 가져오는 데 사용될 수 있습니다.

배열 키: 배열 형태로 여러 값을 결합하여 더 복잡한 쿼리 키를 생성할 수 있습니다. 예를 들어, ["user", userId]와 같은 배열 키를 사용하여 특정 사용자의 데이터를 가져올 수 있습니다.

객체 키: 객체 형태로 추가 정보를 포함하여 더 구체적인 쿼리 키를 생성할 수 있습니다. 예를 들어, { type: "post", id: postId }와 같은 객체 키를 사용하여 특정 게시물의 데이터를 가져올 수 있습니다.

쿼리 키의 주요 역할은 다음과 같습니다:

캐시 식별: React Query는 각 쿼리 키에 대한 캐시를 유지 관리합니다. 같은 쿼리 키로 요청된 데이터는 캐시에 저장되며, 같은 키로 요청되는 데이터는 이전에 저장된 캐시를 반환하여 중복 요청을 피하고 성능을 개선합니다.

쿼리 연관성: 쿼리 키를 사용하여 관련된 데이터를 연결할 수 있습니다. 예를 들어, "user"와 "userTodos"라는 두 가지 쿼리 키를 사용하여 사용자 정보와 해당 사용자의 할 일 목록을 관리할 수 있습니다.

캐시 재활용: 쿼리 키를 변경하거나 업데이트하여 데이터의 변화를 감지하고, React Query는 자동으로 변경된 데이터를 다시 가져와 새로운 정보로 캐시를 갱신합니다.

갱신 및 재요청: queryClient.invalidateQueries 함수를 사용하여 특정 쿼리 키의 데이터를 재요청할 수 있습니다. 데이터 변경 후 이 함수를 호출하면 관련된 캐시가 무효화되고 새로운 데이터가 가져와집니다.

쿼리 키를 잘 정의하고 활용함으로써 React Query는 캐시 관리와 데이터 업데이트를 효율적으로 처리할 수 있습니다.

 

----

 

coinId가 조금 이해가 안되었는데 알고보니 이 데이터를 페치한 이 이름의 데이터에서 선별해서 가져올 수 있다. 

그리고 카카오페이에서 react-query에 대한 이야기를 상세하게 써줘서 이해하는데 도움이 되었다.  

 

// quires/useTodosQuery.ts
// API 상태를 불러오기 위한 React Query Custom Hook

// ...전략

const useTodosQuery = () => {
  return useQuery(QUERY_KEY, fetcher, { refetchOnWindowFocus: true });
};

export default useTodosQuery;

 

refetchOnWindowFocus라는 기능이 있는데 윈도우 화면을 벗어났다 들어오면 data다 갱신되게 할 수 있다. 

 

더 딥하게 보고 싶지만 오늘은 사용법에 대해서만 기록한다.