Tanstack Query는 서버 상태 관리 라이브러리로, 복잡하고 장황한 코드를 필요로 하지 않고, 상태 관리와 데이터 fetching을 간편하게 해준다.
기존의 Redux나 Recoil 등의 상태 관리 라이브러리는 클라이언트와 서버 상태를 함께 관리하는데에 반해 React Query는 서버 상태를 분리하여 관리할 수 있어 더 직관적이고 효율적으로 상태를 관리할 수 있다.
다양한 옵션들을 활용해 캐싱, 에러 처리, suspense, refresh, 데이터 fetching 조건 설정 등을 선언적이고 간편하게 이용할 수 있다.
import { useEffect, useState } from "react";
const getServerData = async () => {
const data = await fetch("<https://jsonplaceholder.typicode.com/posts>").then((response) => response.json());
return data;
};
export default function App() {
const [state, setState] = useState([]);
useEffect(() => {
getServerData()
.then((dataList) => setState(dataList))
.catch((e) => setState([]));
}, []);
return <div>{JSON.stringify(state)}</div>;
}
import { useQuery } from '@tanstack/react-query';
const getServerData = async () => {
const data = await fetch("<https://jsonplaceholder.typicode.com/posts>").then((response) => response.json());
return data;
};
export default function App() {
const { data } = useQuery({
queryKey: ['data'],
queryFn: getServerData
});
return <div>{JSON.stringify(data)}</div>;
}
위의 코드와 아래의 코드는 같은 결과를 갖게 된다. tanstack query를 사용하는 것이 더 간략해 보인다.
그럼 Next.js에서는 어떻게 사용해야할까?
yarn add @tanstack/react-query @tanstack/react-query-devtools
// In Next.js, this file would be called: app/providers.jsx
"use client";
// Since QueryClientProvider relies on useContext under the hood, we have to put 'use client' on top
import {
isServer,
QueryClient,
QueryClientProvider,
} from "@tanstack/react-query";
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 60 * 1000,
},
},
});
}
let browserQueryClient: QueryClient | undefined = undefined;
function getQueryClient() {
if (isServer) {
// Server: always make a new query client
return makeQueryClient();
} else {
// Browser: make a new query client if we don't already have one
// This is very important, so we don't re-make a new client if React
// suspends during the initial render. This may not be needed if we
// have a suspense boundary BELOW the creation of the query client
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
}
}
export default function Providers({ children }: { children: React.ReactNode }) {
// NOTE: Avoid useState when initializing the query client if you don't
// have a suspense boundary between this and the code that may
// suspend because React will throw away the client on the initial
// render if it suspends and there is no boundary
const queryClient = getQueryClient();
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
}
// In Next.js, this file would be called: app/layout.jsx
import Providers from './providers'
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<Providers>{children}</Providers>
</body>
</html>
)
이렇게 사용하면 Next.js 프로젝트 전역에서 Tanstack Query를 사용할 수 있게 된다.