tanstack-react-query
4
总安装量
4
周安装量
#54002
全站排名
安装命令
npx skills add https://github.com/gilbertopsantosjr/fullstacknextjs --skill tanstack-react-query
Agent 安装分布
opencode
2
cursor
2
codex
2
gemini-cli
2
replit
1
Skill 文档
TanStack React Query Expert
Expert guidance for idiomatic React Query (TanStack Query v5) patterns in React applications, with special focus on ZSA server action integration via @saas4dev/core.
Core Hooks
From @saas4dev/core (Server Actions)
import {
useServerActionQuery,
useServerActionMutation,
useServerActionInfiniteQuery,
} from '@saas4dev/core'
From @tanstack/react-query (Direct API)
import {
useQuery,
useMutation,
useInfiniteQuery,
useQueryClient,
} from '@tanstack/react-query'
Decision Tree
Need to fetch data?
âââ From server action â useServerActionQuery
âââ From REST/fetch directly â useQuery
âââ Paginated/infinite â useServerActionInfiniteQuery or useInfiniteQuery
Need to modify data?
âââ From server action â useServerActionMutation
âââ From REST/fetch directly â useMutation
After mutation, what cache behavior?
âââ Simple: just invalidate â queryClient.invalidateQueries()
âââ Update specific item â queryClient.setQueryData()
âââ Need instant feedback â Optimistic update pattern
Quick Patterns
Server Action Query
const { data, isLoading } = useServerActionQuery(listUsersAction, {
input: { status: 'active' },
queryKey: ['users', 'list', { status: 'active' }],
})
Server Action Mutation with Invalidation
const queryClient = useQueryClient()
const mutation = useServerActionMutation(createUserAction, {
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] })
toast.success('User created')
},
onError: (error) => toast.error(error.message),
})
Optimistic Update
const mutation = useServerActionMutation(updateTodoAction, {
onMutate: async (newData) => {
await queryClient.cancelQueries({ queryKey: ['todos', newData.id] })
const previous = queryClient.getQueryData(['todos', newData.id])
queryClient.setQueryData(['todos', newData.id], (old) => ({ ...old, ...newData }))
return { previous }
},
onError: (err, newData, context) => {
queryClient.setQueryData(['todos', newData.id], context?.previous)
},
onSettled: (data, err, variables) => {
queryClient.invalidateQueries({ queryKey: ['todos', variables.id] })
},
})
Query Key Structure
Hierarchy Pattern
['entity'] // All of entity
['entity', 'list'] // All lists
['entity', 'list', { filters }] // Filtered list
['entity', 'detail', id] // Single item
['entity', id, 'nested'] // Nested resource
Query Key Factory
export const userKeys = {
all: ['users'] as const,
lists: () => [...userKeys.all, 'list'] as const,
list: (filters: Filters) => [...userKeys.lists(), filters] as const,
details: () => [...userKeys.all, 'detail'] as const,
detail: (id: string) => [...userKeys.details(), id] as const,
}
Configuration Defaults
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
gcTime: 5 * 60 * 1000, // 5 minutes
retry: 1,
refetchOnWindowFocus: false,
},
},
})
Best Practices
- Query Keys: Use hierarchical keys; invalidate broadly, fetch specifically
- Mutations: Always invalidate or update related queries on success
- Loading States: Use
isLoadingfor first load,isFetchingfor background updates - Error Handling: Handle in
onErrorcallback; show user-friendly messages - Optimistic Updates: Use for high-confidence mutations; always implement rollback
- Conditional Queries: Use
enabledoption, not conditional hook calls - Derived Data: Use
selectto transform data; keeps original in cache
References
Detailed patterns and examples:
- query-patterns.md: Query keys, useQuery, pagination, parallel/dependent queries
- mutation-patterns.md: Mutations, cache invalidation, optimistic updates, rollback
- advanced-patterns.md: Custom hooks, prefetching, SSR hydration, testing
Skill Interface
When using this skill, provide:
{
"apiDescription": "REST/GraphQL endpoints, methods, parameters, response shapes",
"uiScenario": "What the UI needs (e.g., 'List with pagination', 'Edit form with instant feedback')",
"constraints": "React Query v5, fetch vs axios, suspense vs traditional",
"currentCode": "(optional) Existing code to improve"
}
Response includes:
- recommendations: Query keys, hooks, invalidation strategy
- exampleCode: React components/hooks demonstrating patterns
- notes: Why these patterns were chosen