Loading...
Loading...
Generate TanStack Query hooks for efficient server state management. Creates query hooks, mutation hooks with automatic cache invalidation, and handles loading/error states. Use when fetching data from APIs or databases in React components.
npx skill4agent add jpborrelli/wachines-plugin-ironman tanstack-query-hooks| Data Type | Pattern | Use Case |
|---|---|---|
| Read-only data | | Get users, get transactions, get products |
| Create/Update/Delete | | Create user, update transaction, delete product |
| Paginated lists | | Infinite scroll, load more |
| Dependent queries | Chained | Fetch user → then user's posts |
// ✅ Hierarchical keys (RECOMMENDED)
QUERY_KEYS.users.root(estId) // ['users', 'est-123']
QUERY_KEYS.users.detail(estId, userId) // ['users', 'est-123', 'detail', 'user-456']
// ❌ Flat keys (avoid)
['users'] // Can't target specific userHook: useTransacciones
Type: query
Entity: transacciones
Params: entityId
Returns: transacciones[], loading, errorimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { QUERY_KEYS } from '@/lib/queryKeys';
import { supabase } from '@/lib/supabase';const { data, isLoading, error, refetch } = useQuery({
queryKey: QUERY_KEYS.entity.root(id),
queryFn: async () => {
const { data, error } = await supabase
.from('table')
.select('*')
.eq('id', id);
if (error) throw error;
return data;
},
enabled: !!id, // Only run if id exists
staleTime: 5 * 60 * 1000, // 5 minutes
});const mutation = useMutation({
mutationFn: async (data) => {
const { data: result, error } = await supabase
.from('table')
.insert(data)
.select()
.single();
if (error) throw error;
return result;
},
onSuccess: () => {
// ✅ CRITICAL: Invalidate related queries
queryClient.invalidateQueries({
queryKey: QUERY_KEYS.entity.root(id)
});
}
});If it comes from the server → TanStack Query If it's only UI state → useState
import { QueryClient } from '@tanstack/react-query';
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 min cache
gcTime: 10 * 60 * 1000, // 10 min garbage collection
refetchOnWindowFocus: true, // Refetch on tab focus
retry: 3, // Retry 3 times on error
refetchOnMount: false, // Don't refetch if cache fresh
},
mutations: {
retry: 1, // Retry mutations once
}
}
});import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>useStateuseEffectQUERY_KEYS/lib/queryKeys.tsstaleTimeenabledonSuccessenabledType: query
Entity: proveedores
Params: entityIdType: mutation
Action: createProveedor
Invalidates: proveedores listType: query
Entity: childDetail
Params: entityId, childId
DependsOn: entityId exists