smithery/aiskillstore

pitfalls-tanstack-query

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.

Installation

$ npx skills add smithery/aiskillstore --skill pitfalls-tanstack-query

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/aiskillstore · top by installs.

npx skills add smithery/aiskillstore

Browse all from smithery/aiskillstore

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 2,646 B
  • docs SUMMARY.md 248 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

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