If you're tired of juggling useEffect, useState, and manual refetching logic TanStack Query (aka React Query) might just be your new favorite tool. It’s built for React devs who want smooth, reliable data fetching with smart caching and fewer headaches.
Let's walk through the basics of setting it up and making your first query.
Why TanStack Query?
This library shines when you're dealing with:
- REST or GraphQL APIs
- Multiple loading states
- Auto caching and refetching
- Background updates (yep, it's magic)
If you've ever written the same useEffect + fetch + isLoading boilerplate in multiple components, you’ll love this.
Install It
First, install the core library:
Set Up the Provider You'll need to wrap your app with QueryClientProvider:
1import { QueryClient, QueryClientProvider } from "@tanstack/react-query";2 3const queryClient = new QueryClient();4 5<QueryClientProvider client={queryClient}>6 <App />7</QueryClientProvider>;
Your First Query Let's say we're fetching users:
1import { useQuery } from "@tanstack/react-query";2 3const fetchUsers = async () => {4 const res = await fetch("https://jsonplaceholder.typicode.com/users");5 if (!res.ok) throw new Error("Failed to fetch users");6 return res.json();7};8 9export function UsersList() {10 const { data, isLoading, isError, error } = useQuery({11 queryKey: ["users"],12 queryFn: fetchUsers,13 });14 15 if (isLoading) return <p>Loading users...</p>;16 if (isError) return <p>Error: {error.message}</p>;17 18 return (19 <ul>20 {data.map((user) => (21 <li key={user.id}>{user.name}</li>22 ))}23 </ul>24 );25}
Mutations for POST, PUT, DELETE
1import { useMutation } from "@tanstack/react-query";2 3const addUser = async (user) => {4 const res = await fetch("/api/users", {5 method: "POST",6 body: JSON.stringify(user),7 headers: { "Content-Type": "application/json" },8 });9 return res.json();10};11 12function AddUserForm() {13 const mutation = useMutation({ mutationFn: addUser });14 15 const handleSubmit = (e) => {16 e.preventDefault();17 const user = { name: "Sanjid" };18 mutation.mutate(user);19 };20 21 return (22 <>23 <form onSubmit={handleSubmit}>24 <button type="submit">Add User</button>25 </form>26 {mutation.isPending && <p>Sending...</p>}27 {mutation.isSuccess && <p>User added!</p>}28 </>29 );30}
Debugging Like a Pro Install Devtools for visual inspection of cache and query states:
1import { ReactQueryDevtools } from "@tanstack/react-query-devtools";2 3<ReactQueryDevtools initialIsOpen={false} />;
Wrapping Up TanStack Query eliminates 90% of the boilerplate that comes with managing server data in React. It's my go-to in almost every project, especially when building dashboards or internal tools.
Once you start using it—you'll rarely look back.