Back to Notes

TanStack Query Setup in Next.jsTanStack Query Setup in Next.js

10 months ago

TanStack Query Setup in Next.js

TanStack Query (formerly React Query) simplifies data fetching, caching, and revalidation in React apps β€” including Next.js.

πŸ”— Official Docs: https://tanstack.com/query/latest


πŸ“¦ 1. Install the Required Packages

Install both runtime and dev dependencies:

bash
npm install @tanstack/react-query npm install -D @tanstack/eslint-plugin-query

🧱 2. Add TanStackProvider Wrapper

Create a file like tanstack-provider.tsx inside your project:

tsx
// app/tanstack-provider.tsx "use client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { useState } from "react"; interface TanStackProviderProps { children: React.ReactNode; } export const TanStackProvider = ({ children }: TanStackProviderProps) => { const [queryClient] = useState(() => new QueryClient()); return ( <QueryClientProvider client={queryClient}> {children} </QueryClientProvider> ); };

🧩 3. Wrap Your App with the Provider

In layout.tsx or app.tsx:

tsx
// app/layout.tsx or app/page.tsx import { TanStackProvider } from "./tanstack-provider"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <TanStackProvider>{children}</TanStackProvider> </body> </html> ); }

⚑ 4. Quick Start Example (Client Component)

tsx
"use client"; import { useQuery, useMutation, useQueryClient, } from "@tanstack/react-query"; const getTodos = async () => { const res = await fetch("/api/todos"); return res.json(); }; const postTodo = async (todo: { id: number; title: string }) => { const res = await fetch("/api/todos", { method: "POST", body: JSON.stringify(todo), headers: { "Content-Type": "application/json" }, }); return res.json(); }; export default function Todos() { const queryClient = useQueryClient(); const { data } = useQuery({ queryKey: ["todos"], queryFn: getTodos, }); const mutation = useMutation({ mutationFn: postTodo, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["todos"] }); }, }); return ( <div> <ul> {data?.map((todo: any) => ( <li key={todo.id}>{todo.title}</li> ))} </ul> <button onClick={() => { mutation.mutate({ id: Date.now(), title: "Do Laundry", }); }} > Add Todo </button> </div> ); }

πŸ”„ Revalidation

You can use:

  • invalidateQueries({ queryKey }) β€” to manually trigger refetch
  • refetchInterval β€” to refetch periodically
  • refetchOnWindowFocus: true β€” to refetch on tab switch

βœ… Done!

You're now ready to use useQuery, useMutation , and more anywhere in your Next.js client components. Happy querying!


Tech Stack: Next.js, TanStack Query