gs-tanstack-react-query

TanStack React Query for data fetching with Clean Architecture. Queries return DTOs, mutations call server actions. Use when working with useQuery, useMutation, cache invalidation, or integrating ZSA server actions.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "gs-tanstack-react-query" with this command: npx skills add gilbertopsantosjr/fullstacknextjs/gilbertopsantosjr-fullstacknextjs-gs-tanstack-react-query

TanStack React Query (Clean Architecture)

Data Flow with DTOs

useServerActionQuery → Server Action → Use Case → DTO

All query responses are DTOs, not Entities. TypeScript types should reflect this.

Core Hooks

import {
  useServerActionQuery,
  useServerActionMutation,
  useServerActionInfiniteQuery,
} from '@saas4dev/core'

import { useQueryClient } from '@tanstack/react-query'

Query with DTO Types

import type { CategoryDTO } from '@/features/category'
import { listCategoriesAction, getCategoryAction } from '@/features/category'

// List query - returns CategoryDTO[]
const { data, isLoading } = useServerActionQuery(listCategoriesAction, {
  input: { status: 'active' },
  queryKey: ['categories', 'list', { status: 'active' }],
})

// data.items is CategoryDTO[]

// Single item query
const { data: category } = useServerActionQuery(getCategoryAction, {
  input: { id },
  queryKey: ['categories', 'detail', id],
})

// category is CategoryDTO

Mutation with Invalidation

import { createCategoryAction } from '@/features/category'

const queryClient = useQueryClient()

const mutation = useServerActionMutation(createCategoryAction, {
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: ['categories'] })
    toast.success('Category created')
  },
  onError: (error) => toast.error(error.message),
})

// Usage
mutation.mutate({ name: 'New Category' })

Query Key Pattern

// Hierarchical keys for precise invalidation
['categories']                           // All categories
['categories', 'list']                   // All lists
['categories', 'list', { status }]       // Filtered list
['categories', 'detail', id]             // Single item

Query Key Factory

export const categoryKeys = {
  all: ['categories'] as const,
  lists: () => [...categoryKeys.all, 'list'] as const,
  list: (filters: { status?: string }) => [...categoryKeys.lists(), filters] as const,
  details: () => [...categoryKeys.all, 'detail'] as const,
  detail: (id: string) => [...categoryKeys.details(), id] as const,
}

Optimistic Update

const mutation = useServerActionMutation(updateCategoryAction, {
  onMutate: async (newData) => {
    await queryClient.cancelQueries({ queryKey: ['categories', 'detail', newData.id] })
    const previous = queryClient.getQueryData<CategoryDTO>(['categories', 'detail', newData.id])

    queryClient.setQueryData<CategoryDTO>(
      ['categories', 'detail', newData.id],
      (old) => old ? { ...old, ...newData } : old
    )

    return { previous }
  },
  onError: (err, newData, context) => {
    if (context?.previous) {
      queryClient.setQueryData(['categories', 'detail', newData.id], context.previous)
    }
  },
  onSettled: (_, __, variables) => {
    queryClient.invalidateQueries({ queryKey: ['categories', 'detail', variables.id] })
  },
})

Pagination

const { data, fetchNextPage, hasNextPage } = useServerActionInfiniteQuery(
  listCategoriesAction,
  {
    queryKey: ['categories', 'list'],
    getNextPageParam: (lastPage) => lastPage.nextCursor,
    initialPageParam: undefined,
    input: ({ pageParam }) => ({ cursor: pageParam, limit: 20 }),
  }
)

// data.pages[].items is CategoryDTO[]

Best Practices

  1. Type with DTOs - useQueryData<CategoryDTO>() not Category
  2. Actions only - Never call Use Cases from components
  3. Hierarchical keys - Invalidate broadly, fetch specifically
  4. Error handling - Show domain exception messages
  5. Optimistic updates - Always implement rollback

References

  • Web Client: skills/nextjs-web-client/SKILL.md
  • Server Actions: skills/nextjs-server-actions/SKILL.md

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

tanstack-react-query

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

clinic-visit-prep

帮助患者整理就诊前问题、既往记录、检查清单与时间线,不提供诊断。;use for healthcare, intake, prep workflows;do not use for 给诊断结论, 替代医生意见.

Archived SourceRecently Updated
Automation

changelog-curator

从变更记录、提交摘要或发布说明中整理对外 changelog,并区分用户价值与内部改动。;use for changelog, release-notes, docs workflows;do not use for 捏造未发布功能, 替代正式合规审批.

Archived SourceRecently Updated