टैनस्टैक क्वेरी (पूर्व में रिएक्ट क्वेरी) 2026 में रिएक्ट, व्यू, सॉलिड और एंगुलर अनुप्रयोगों में सर्वर स्थिति प्रबंधन के लिए स्वर्ण मानक है। यह मैन्युअल डेटा लाने, कैशिंग और सिंक्रोनाइज़ेशन की जटिलता को समाप्त करता है, सरल, शक्तिशाली हुक के साथ यूज़इफ़ेक्ट कोड की सैकड़ों पंक्तियों को प्रतिस्थापित करता है।
📋 Table of Contents
टैनस्टैक क्वेरी क्यों?
- कोई बॉयलरप्लेट नहीं– Redux + फ़ेच + यूज़इफ़ेक्ट पैटर्न को प्रतिस्थापित करता है
- स्वचालित कैशिंग– कुंजी द्वारा कैश किया गया डेटा, आवश्यकता पड़ने पर ताज़ा किया जाता है
- बैकग्राउंड रीफ़ेचिंग– पुराना डेटा तुरंत दिखाया गया, पृष्ठभूमि में ताज़ा डेटा
- लोडिंग/त्रुटि स्थिति– अंतर्निर्मित, कोई मैन्युअल राज्य प्रबंधन नहीं
- आशावादी अद्यतन– सर्वर की पुष्टि से पहले यूआई अपडेट
- देवटूल्स– कैश का निरीक्षण करें, पुनः प्राप्त करें, ब्राउज़र एक्सटेंशन से अमान्य करें
स्थापना और सेटअप
npm install @tanstack/react-query @tanstack/react-query-devtools
# Optional: axios for HTTP
npm install axios
// main.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes (data considered fresh)
gcTime: 10 * 60 * 1000, // 10 minutes (cache garbage collection)
retry: 2, // retry failed requests twice
refetchOnWindowFocus: true, // refetch when tab becomes active
},
},
});
function App() {
return (
<QueryClientProvider client={queryClient}>
<Router />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}
यूज़क्वेरी – डेटा प्राप्त करना
import { useQuery, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';
interface User {
id: number;
name: string;
email: string;
}
// Query function
async function fetchUser(id: number): Promise<User> {
const { data } = await axios.get(`/api/users/${id}`);
return data;
}
// Component using query
function UserProfile({ userId }: { userId: number }) {
const {
data: user,
isLoading,
isError,
error,
isFetching, // true when refetching in background
isStale, // true when data is stale
refetch, // manually trigger refetch
} = useQuery({
queryKey: ['users', userId], // unique cache key
queryFn: () => fetchUser(userId),
enabled: userId > 0, // only fetch when userId is valid
staleTime: 60_000, // fresh for 1 minute
select: (data) => data, // transform data before returning
});
if (isLoading) return <Skeleton />;
if (isError) return <ErrorBoundary error={error} />;
return (
<div>
{isFetching && <small>Refreshing...</small>}
<h1>{user.name}</h1>
<p>{user.email}</p>
<button onClick={() => refetch()}>Refresh</button>
</div>
);
}
समानांतर प्रश्न
// Fetch multiple queries simultaneously
function Dashboard() {
const [userQuery, postsQuery, statsQuery] = useQueries({
queries: [
{ queryKey: ['user', 1], queryFn: () => fetchUser(1) },
{ queryKey: ['posts'], queryFn: fetchPosts },
{ queryKey: ['stats'], queryFn: fetchStats },
],
});
if (userQuery.isLoading || postsQuery.isLoading) return <Loading />;
return (
<div>
<UserCard user={userQuery.data} />
<PostList posts={postsQuery.data} />
<StatsPanel stats={statsQuery.data} />
</div>
);
}
उपयोग उत्परिवर्तन – बनाना, अद्यतन करना, हटाना
import { useMutation, useQueryClient } from '@tanstack/react-query';
async function createPost(post: { title: string; content: string }) {
const { data } = await axios.post('/api/posts', post);
return data;
}
function NewPostForm() {
const queryClient = useQueryClient();
const { mutate, isPending, isError, error } = useMutation({
mutationFn: createPost,
// Called when mutation succeeds
onSuccess: (newPost) => {
// Option 1: Invalidate cache (triggers refetch)
queryClient.invalidateQueries({ queryKey: ['posts'] });
// Option 2: Update cache directly (no refetch)
queryClient.setQueryData(['posts'], (old: Post[]) => [...old, newPost]);
// Show toast notification
toast.success('Post created!');
},
onError: (error) => {
toast.error(`Failed: ${error.message}`);
},
});
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const form = e.currentTarget;
mutate({
title: (form.title as HTMLInputElement).value,
content: (form.content as HTMLTextAreaElement).value,
});
};
return (
<form onSubmit={handleSubmit}>
<input name="title" required placeholder="Title" />
<textarea name="content" required placeholder="Content" />
<button type="submit" disabled={isPending}>
{isPending ? 'Creating...' : 'Create Post'}
</button>
{isError && <p className="error">{error.message}</p>}
</form>
);
}
आशावादी अद्यतन
const { mutate: likePost } = useMutation({
mutationFn: (postId: number) => axios.post(`/api/posts/${postId}/like`),
onMutate: async (postId) => {
// Cancel any outgoing refetches
await queryClient.cancelQueries({ queryKey: ['posts', postId] });
// Snapshot the previous value
const previousPost = queryClient.getQueryData(['posts', postId]);
// Optimistically update the UI
queryClient.setQueryData(['posts', postId], (old: Post) => ({
...old,
likes: old.likes + 1,
}));
// Return context for rollback
return { previousPost };
},
// Roll back on error
onError: (error, postId, context) => {
queryClient.setQueryData(['posts', postId], context?.previousPost);
toast.error('Failed to like post');
},
// Always refetch after mutation
onSettled: (data, error, postId) => {
queryClient.invalidateQueries({ queryKey: ['posts', postId] });
},
});
अनंत प्रश्न
import { useInfiniteQuery } from '@tanstack/react-query';
function InfinitePostList() {
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['posts', 'infinite'],
queryFn: ({ pageParam = 1 }) => fetchPosts(pageParam),
initialPageParam: 1,
getNextPageParam: (lastPage, pages) =>
lastPage.hasMore ? pages.length + 1 : undefined,
});
return (
<div>
{data?.pages.map((page, i) => (
<React.Fragment key={i}>
{page.posts.map(post => <PostCard key={post.id} post={post} />)}
</React.Fragment>
))}
<button onClick={() => fetchNextPage()} disabled={!hasNextPage || isFetchingNextPage}>
{isFetchingNextPage ? 'Loading...' : hasNextPage ? 'Load More' : 'All loaded'}
</button>
</div>
);
}
कस्टम क्वेरी हुक
// hooks/useUsers.ts — reusable query hooks
export function useUsers(filters?: UserFilters) {
return useQuery({
queryKey: ['users', filters],
queryFn: () => fetchUsers(filters),
select: (data) => ({
users: data.users,
total: data.total,
}),
});
}
export function useUser(id: number) {
const queryClient = useQueryClient();
return useQuery({
queryKey: ['users', id],
queryFn: () => fetchUser(id),
// Pre-populate from list query
initialData: () => {
const usersQuery = queryClient.getQueryData<UsersResponse>(['users']);
return usersQuery?.users.find(u => u.id === id);
},
initialDataUpdatedAt: () =>
queryClient.getQueryState(['users'])?.dataUpdatedAt,
});
}
export function useUpdateUser() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (user: Partial<User> & { id: number }) =>
axios.patch(`/api/users/${user.id}`, user).then(r => r.data),
onSuccess: (updated) => {
queryClient.setQueryData(['users', updated.id], updated);
queryClient.invalidateQueries({ queryKey: ['users'] });
},
});
}
2026 में टैनस्टैक क्वेरी विशिष्ट रिएक्ट डेटा फ़ेचिंग कोड में बॉयलरप्लेट के 80% को समाप्त कर देती है। पढ़ने के लिए यूज़क्वेरी से शुरुआत करें और लिखने के लिए यूज़म्यूटेशन से शुरुआत करें। सरल कैश अपडेट के लिए इनवैलिडेटक्वेरीज़ का उपयोग करें और आशावादी अपडेट के लिए setQueryData का उपयोग करें। सीखने का निवेश हर प्रोजेक्ट पर लाभांश देता है।
🔗 Share this article
✍️ Leave a Comment