Loading...
Loading...
TanStack Query (React Query) for async operations, data fetching, caching, and state management. Use when fetching server data, managing async operations, caching responses, handling mutations, or any operation that benefits from automatic state management and caching.
npx skill4agent add blockmatic/basilic-skills tanstack-query-v5queries/isLoadingerrorisErrorqueryFnuseQuery<ResponseType>(...)@lukemorales/query-key-factoryexport const userKeys = {
all: ['users'] as const,
detail: (id: string) => [...userKeys.all, id] as const,
list: (filters?: Filters) => [...userKeys.all, 'list', filters] as const,
}
// Usage
import { useQuery } from '@tanstack/react-query'
import { userKeys } from '@/queries/users'
const { data, isLoading, error } = useQuery({
queryKey: userKeys.detail(userId),
queryFn: () => fetchUser(userId),
})@lukemorales/query-key-factoryimport { createQueryKeys } from '@lukemorales/query-key-factory'
export const users = createQueryKeys('users', {
detail: (id: string) => ({
queryKey: [id],
queryFn: () => fetchUser(id),
}),
})queryFn// Server data fetching (traditional)
const { data } = useQuery({
queryKey: ['users', userId],
queryFn: () => fetchUser(userId),
})
// Local computation (no network)
const { data } = useQuery({
queryKey: ['fibonacci', n],
queryFn: () => computeFibonacci(n),
})
// localStorage read
const { data: settings } = useQuery({
queryKey: ['user-settings'],
queryFn: () => Promise.resolve(
JSON.parse(localStorage.getItem('settings') || '{}')
),
})
// File operation
const { data } = useQuery({
queryKey: ['file-content', path],
queryFn: () => readFile(path),
})import { useMutation, useQueryClient } from '@tanstack/react-query'
import { userKeys } from '@/queries/users'
function useCreateUser() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (data: CreateUserInput) => {
const response = await createUser(data)
return response
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: userKeys.all })
},
})
}import { useInfiniteQuery } from '@tanstack/react-query'
import { users } from '@/queries/users'
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['users', 'infinite'],
queryFn: ({ pageParam = 0 }) => fetchUsers({ page: pageParam }),
getNextPageParam: (lastPage, pages) => lastPage.nextPage,
initialPageParam: 0,
})import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState } from 'react'
function Providers({ children }: { children: ReactNode }) {
const [queryClient] = useState(() => new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
retry: 1,
refetchOnWindowFocus: false,
},
},
}))
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}import { useQuery } from '@tanstack/react-query'
import { apiClient } from '@/lib/api-client'
export function useHealthCheck() {
return useQuery({
queryKey: ['health'],
queryFn: () => apiClient.GET('/health').then(r => r.data),
})
}// hooks/useUser.ts
import { useQuery } from '@tanstack/react-query'
import { userKeys } from '@/queries/users'
export function useUser(userId: string) {
return useQuery({
queryKey: userKeys.detail(userId),
queryFn: () => fetchUser(userId),
})
}nuqsahooks.useSetStateahooks.useLocalStorageStateuseState