TanStack Query 는 구 react-query 로, 데이터 패칭 (API 요청)과 캐싱을 간편하게 관리할 수 있는 라이브러리이다. Redux 의 경우 비동기 처리를 하려면 redux-thunk 또는 redux-saga 같은 추가 라이브러리가 필요하지만, TanStack Query 는 기본적으로 비동기 상태 관리 기능을 제공한다.
📌 CHECK POINT
- Redux는 전역 상태 관리에 강하다.
- TanStack Query는 비동기 데이터 관리 (API 요청) 에 강하다.
- 프로젝트에 따라 둘을 함께 사용하기도 한다.
// QueryClientProvider : queryClient 를 전역으로 관리할 수 있도록 제공하는 Provider
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import PokemonList from "./PokemonList";
// queryClient 객체를 생성해야 한다. API요청과 캐싱을 관리하는 핵심 역할!
// new 는 최초 한 번만!!! 추후에 사용할 시에는 use QueryClient
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<PokemonList />
</QueryClientProvider>
);
}
export default App;
import { useQuery } from "@tanstack/react-query";
// data 를 fetch 해오기
// `useQuery` 에서 `queryFn` 에 들어가는 함수는 반드시 `Promise` 를 반환하는 비동기 함수여야 한다!
async function fetchPokemon() {
const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=10");
return response.json();
}
function PokemonList() {
// useQuery 는 데이터를 구조 분해 할당을 통해 받아온다.
// 1. data: API에서 가져온 실제 데이터 (data: pokemonData 처럼 변수명 변경 가능)
// 2. isLoading: 데이터가 로딩 중인지 여부 (true일 경우, 아직 데이터를 가져오는 중)
// 3. error: 요청이 실패했을 경우 오류 정보
const { data, isLoading, error } = useQuery({
queryKey: ["pokemon"], // 데이터 식별의 고유 키
queryFn: fetchPokemon, // 반드시 Promise 객체를 반환
});
// 로딩 중 => isLoading / error 발생 => error 로 UI 렌더링 관리
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{data.results.map((pokemon) => (
<li key={pokemon.name}>{pokemon.name}</li>
))}
</ul>
);
}
export default PokemonList;
🔗 queryKey
- 데이터를 식별하는 고유 키
queryKey가 동일하면 캐싱된 데이터를 보여주고, 데이터가 변경되면refetch한다.🔗 queryFn
- 데이터를 가져오는 함수 (비동기 API 요청을 처리)
- 이 함수는 반드시
Promise객체를 반환한다.
-> useQuery 자체에 fetch 기능이 내장되어 있기 때문에, Promise 객체로 반환해줘야 제대로 동작할 수 있다.- 이미 데이터가 캐싱되어 있다면, API 요청을 생략하고 기존 데이터를 활용한다.
- 함수 형태로 넘기는 이유는
useQuery가 자동으로 API 요청을 관리해주기 때문에, 콜백함수로 넘겨주면 필요할 때에만 알아서 실행하기 때문.
생각보다 간단한 듯,,아닌 듯,,,? 많이 써먹어 봐야겠다.