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 refetchrefetchIntervalβ to refetch periodicallyrefetchOnWindowFocus: 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