tanstack-query는 거의 필수적으로 요즘 웹개발에 사용하는데 만약 클라이언트 상태관리로 Jotai를 선택했다면 두개의 상태관리 시스템을 병렬로 관리해줘야한다.
하지만 Jotai에서는 여러 extensions을 제공하고, 그중 query에 대한것을 사용해보자.
npm install jotai-tanstack-query @tanstack/query-core
공식문서에 따라 설치해준다. 언제나 이 블로그가 아니고 공식문서 먼저 봐라
jotai-tanstack-query만 사용한다면 Provider 설정만으로 충분하며, client 인스턴스 별도 설정은 필요하지 않음.
tanstack-query와 같이 쓸 때만 client 동기화 필요.
import {Api} from "./sdk/api";
import {atom, useAtom, useAtomValue} from "jotai";
import {atomWithQuery} from "jotai-tanstack-query";
const sdk = new Api({
// baseURL: "https://pokeapi.co/api/v2",
});
const pageAtom = atom(0);
const offsetAtom = atom((get) => {
const page = get(pageAtom);
return page * 10;
});
// 이런 파생상태도 만들 수 있다 정도로 이해
const goldPokeListAtom = atom(get => {
const res = get(pokeListAtom)
return {
...res,
data: res.data?.data.results?.map(item => {
return {
...item,
name: '금' + item.name
}
})
}
})
const pokeListAtom = atomWithQuery(get => {
const offset = get(offsetAtom)
return {
queryKey: ["pokemonlist", offset],
queryFn: () =>
sdk.api.pokemonList({
limit: 10,
offset,
}),
}
})
function App() {
const [page, setPage] = useAtom(pageAtom);
const {isError, isLoading, error, data} = useAtomValue(goldPokeListAtom)
if (isLoading) {
return <h1>로딩중</h1>;
}
if (isError) {
return <h1>{error.message}</h1>;
}
return (
<>
<div>{JSON.stringify(data)}</div>
<button onClick={() => setPage(page - 1)}>-</button>
<button onClick={() => setPage(page + 1)}>+</button>
</>
);
}
export default App;
atomWithQuery는 내부적으로 TanStack Query의 useQuery 훅과 동일한 결과 객체를 Jotai atom으로 래핑하여 제공한다. 따라서 TanStack Query의 모든 기능과 상태 정보를 Jotai의 atom 시스템을 통해 접근할 수 있게 됨(앱 어디에서나 동일한 쿼리 결과에 접근).
적절히 사용하면 유용할것같다 (헤더, 사이드바 등 여러 곳에 동일한 데이터가 필요할때?)
const router = createBrowserRouter(createRoutesFromElements(
<Route element={<RootLayout/>}>
<Route path='/tanstack-jotai' element={<Tanstack_Jotai/>}/>
</Route>
))
const client = new QueryClient({
defaultOptions: {
queries: {
//defualtOptions설정
}
}
})
const HydrateAtoms: FC<PropsWithChildren> = ({children}) => {
useHydrateAtoms([[queryClientAtom, client]])
return children
}
createRoot(document.getElementById('root')!).render(
<StrictMode>
<HydrateAtoms>
<QueryClientProvider client={client}>
<RouterProvider router={router}/>
{import.meta.env.MODE === 'develop' && <ReactQueryDevtools/>}
</QueryClientProvider>
</HydrateAtoms>
</StrictMode>
)
extension으로 Jotai를 통해 Tanstack-Query의 기능을 사용하려면 Tanstack Query의 client 인스턴스를 Jotai의 queryClientAtom에 연결해야한다. (동일한 클라이언트 사용을 위해)