Agent Skills: TanStack Query v5 Pitfalls

TanStack Query v5 patterns and common pitfalls. Use when implementing data fetching, cache invalidation, or debugging stale data issues. Triggers on: useQuery, useMutation, queryKey, invalidate, TanStack, React Query.

UncategorizedID: aiskillstore/marketplace/pitfalls-tanstack-query

Install this agent skill to your local

pnpm dlx add-skill https://github.com/aiskillstore/marketplace/tree/HEAD/skills/barissozen/pitfalls-tanstack-query

Skill Files

Browse the full folder contents for pitfalls-tanstack-query.

Download Skill

Loading file tree…

skills/barissozen/pitfalls-tanstack-query/SKILL.md

Skill Metadata

Name
pitfalls-tanstack-query
Description
"TanStack Query v5 patterns and common pitfalls. Use when implementing data fetching, cache invalidation, or debugging stale data issues. Triggers on: useQuery, useMutation, queryKey, invalidate, TanStack, React Query."

TanStack Query v5 Pitfalls

Common pitfalls and correct patterns for TanStack Query v5.

When to Use

  • Implementing data fetching with useQuery
  • Setting up mutations with useMutation
  • Debugging stale data or cache issues
  • Reviewing code that uses TanStack Query
  • Migrating from v4 to v5

Workflow

Step 1: Check Query Keys

Verify query keys use full URL paths for proper deduplication.

Step 2: Verify Invalidation

Ensure mutations invalidate relevant queries on success.

Step 3: Check v5 Patterns

Verify v5-specific patterns (isPending vs isLoading).


Correct Usage

// ✅ CORRECT: Full URL path in queryKey
const { data } = useQuery({
  queryKey: ['/api/strategies', strategyId],
  queryFn: () => api.get(`/api/strategies/${strategyId}`),
});

// ✅ CORRECT: Invalidate after mutation
const mutation = useMutation({
  mutationFn: (data) => api.post('/api/strategies', data),
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: ['strategies'] });
  },
});

// ✅ CORRECT: Type responses with schema types
import type { Strategy } from '@shared/schema';
const { data } = useQuery<{ data: Strategy[] }>(...);

Anti-Patterns

// ❌ WRONG: Short queryKey
queryKey: ['strategy']  // Won't dedupe properly

// ❌ WRONG: Forgetting to invalidate
onSuccess: () => { navigate('/'); }  // Stale cache!

// ❌ WRONG: Using isLoading for mutations
mutation.isLoading  // Use isPending in v5

Optimistic Updates

// ✅ Update UI immediately, rollback on error
const mutation = useMutation({
  mutationFn: updateStrategy,
  onMutate: async (newData) => {
    await queryClient.cancelQueries({ queryKey: ['strategy', id] });
    const previous = queryClient.getQueryData(['strategy', id]);

    // Optimistic update
    queryClient.setQueryData(['strategy', id], newData);

    return { previous };
  },
  onError: (err, newData, context) => {
    // Rollback on error
    queryClient.setQueryData(['strategy', id], context.previous);
    toast.error('Update failed');
  },
  onSettled: () => {
    queryClient.invalidateQueries({ queryKey: ['strategy', id] });
  },
});

Quick Checklist

  • [ ] QueryKeys use full URL paths
  • [ ] Mutations invalidate relevant queries
  • [ ] Using isPending (not isLoading) for mutations in v5
  • [ ] Responses typed with schema types