π¦ React Data Fetching using React Query & SWR β The 2025 Optimization Guide
π§² Introduction β Why Use React Query or SWR?
Managing API calls with useEffect
and useState
works fineβuntil it doesn’t. For apps with multiple endpoints, loading spinners, caching, pagination, and real-time updates, you’ll need a smarter data-fetching solution.
React Query and SWR offer powerful abstractions for:
- β‘ Caching and background updates
- π Refetching, retrying, and invalidation
- β Simplified API logic with status tracking
- πΎ Automatic sync with server state
π― In this guide, youβll learn:
- What makes React Query and SWR different
- How to fetch data with each library
- Key features: caching, refetching, and error handling
- Best practices for building scalable data-driven apps
βοΈ 1. What Are React Query and SWR?
Feature | React Query (TanStack) | SWR (Vercel) |
---|---|---|
Purpose | Server-state management | Data fetching & caching |
API style | useQuery , useMutation | useSWR hook |
DevTools | β Yes (DevTools extension) | β οΈ Limited |
Optimistic Updates | β Full support | β οΈ Manual |
Pagination/Infinite | β Built-in | β οΈ Requires custom logic |
Query invalidation | β Manual & automatic | β Not built-in |
π¦ 2. React Query Setup & Usage
β Install:
npm install @tanstack/react-query
β Wrap Your App:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
β
Basic useQuery
Example:
import { useQuery } from '@tanstack/react-query';
const { data, isLoading, error } = useQuery({
queryKey: ['posts'],
queryFn: () => fetch('/api/posts').then(res => res.json())
});
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{data.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
);
π Handles loading, error, and refetching out of the box
β
Perfect for dashboards, filtered lists, and search UIs
π 3. SWR Setup & Usage
β Install:
npm install swr
β
Basic useSWR
Example:
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then(res => res.json());
const { data, error, isLoading } = useSWR('/api/posts', fetcher);
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{data.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
);
β
Zero-config and dead-simple
β
Automatically revalidates on window focus and reconnect
π 4. Refetching & Revalidation
β React Query:
const query = useQuery({ queryKey: ['posts'], queryFn: fetchPosts });
// Manual refetch
<button onClick={() => query.refetch()}>Refresh</button>;
β SWR:
const { data, mutate } = useSWR('/api/posts', fetcher);
// Trigger revalidation
<button onClick={() => mutate()}>Refresh</button>;
π mutate()
can also be used for optimistic updates
π§ 5. Handling Pagination with React Query
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['posts'],
queryFn: ({ pageParam = 1 }) =>
fetch(`/api/posts?page=${pageParam}`).then(res => res.json()),
getNextPageParam: (lastPage) => lastPage.nextPage ?? false,
});
β
Infinite scroll + pagination = built-in
π SWR requires manual implementation of pagination logic
π§ 6. React Query vs SWR β When to Use What?
Use Case | Recommended Tool |
---|---|
Large-scale apps, dashboards | React Query |
Simple fetch + cache (small apps) | SWR |
Infinite queries & mutations | React Query |
SSR/ISR with Next.js | SWR (Vercel-native) |
DevTools & advanced debugging | React Query |
π Best Practices
β
Use queryKey
to scope & cache data correctly
β
Use staleTime
and cacheTime
wisely
β
Use suspense: true
with lazy-loaded components
β
Use mutate
or invalidateQueries
to trigger refetch
β
Wrap logic in custom hooks (e.g., usePosts()
) for reusability
π Summary β Recap & Next Steps
React Query and SWR simplify and supercharge data fetching in React. They give you better caching, revalidation, and status management than manually using useEffect
.
π Key Takeaways:
- React Query = robust async state with powerful APIs
- SWR = lightweight caching-focused data hook
- Both handle loading/error states automatically
- Enable features like caching, retry, refetch, and optimistic updates
- Use for REST, GraphQL, or even local cache/mocks
βοΈ Real-World Relevance:
Used in production by Notion, GitHub, Hashnode, and Vercel to manage UI data with blazing-fast performance and reliability.
β FAQ Section
β Do I still need Redux with React Query or SWR?
β Not for async state. These tools replace Redux for most API-related state.
β Can React Query and SWR work with GraphQL?
β
Yes. Just replace the fetcher
with your GraphQL request logic.
β What is the main difference between SWR and React Query?
β
SWR is minimalist and fetch-focused. React Query is feature-rich, built for large apps, with support for caching, pagination, mutations, and devtools.
β Can I use these in SSR or SSG apps?
β
Yes. SWR is optimized for Next.js. React Query also supports Hydration for SSR/SSG.
β Is caching automatic in these tools?
β
Yes. Both tools cache by default and revalidate automatically depending on config.
Share Now :