Jotai with Tanstack-Query (jotai extension)

Ryan Cho·2025년 2월 7일
0

Jotai with Tanstack-query

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 시스템을 통해 접근할 수 있게 됨(앱 어디에서나 동일한 쿼리 결과에 접근).
적절히 사용하면 유용할것같다 (헤더, 사이드바 등 여러 곳에 동일한 데이터가 필요할때?)

Provider설정 (queryClient 통합)

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에 연결해야한다. (동일한 클라이언트 사용을 위해)

profile
From frontend to fullstack

0개의 댓글