Skip to main content

Query and Mutation

@vef-framework-react/core re-exports TanStack React Query with VEF-specific type wrappers and a pre-configured QueryClient.

QueryClientOptions

QueryClient is not constructed directly — createQueryClient is an internal factory, not exported from the package root. Applications configure these options as ApiClientOptions.query and pass them to createApiClient (see HTTP and API Client):

const queryOptions = {
staleTime: 5_000,
gcTime: 300_000,
showSuccessMessage: message => notification.success(message)
};
OptionTypeDefaultDescription
staleTimenumber5000Time before data is considered stale (ms)
gcTimenumber300000Time before inactive queries are garbage collected (ms)
showSuccessMessage(message: string) => voidCallback to display mutation success messages (see the mutation cache behavior below)

Pre-Configured Defaults

The internal factory configures the QueryClient with these defaults (per-query/mutation options can still override them):

  • Queries: networkMode: "online", retry: false, structuralSharing: true, throwOnError: false, refetchOnMount / refetchOnReconnect / refetchOnWindowFocus: true, retryOnMount: true, queryKeyHashFn: hashKey (the shared stable hasher, so structurally-equal keys hash identically regardless of key order), and experimental_prefetchInRender: true.
  • Mutations: networkMode: "online", retry: false, throwOnError: false, and the same gcTime.
  • Mutation cache onSuccess: when the finished mutation's meta.invalidates is set, every active-or-inactive query matching one of those keys (TanStack matchQuery semantics; already-stale queries are not re-invalidated) is invalidated. When meta.shouldShowSuccessFeedback is not false and the mutation result is a plain object with a message property, that message is passed to showSuccessMessage.

useQuery

import { useQuery } from "@vef-framework-react/core";

const result = useQuery({
queryKey: [findUserPage.key, searchParams],
queryFn: findUserPage
});

useMutation

import { useMutation } from "@vef-framework-react/core";

const mutation = useMutation({
mutationKey: [createUser.key],
mutationFn: createUser,
meta: {
invalidates: [[findUserPage.key]],
shouldShowSuccessFeedback: true
}
});

Mutation Meta Extensions

VEF extends TanStack's MutationMeta with two fields:

FieldTypeDescription
invalidatesArray<QueryKey<never> | QueryKey<unknown>>Query keys to invalidate on successful mutation
shouldShowSuccessFeedbackbooleanWhether to show the success message from the mutation response (default: true)

useInfiniteQuery

import { useInfiniteQuery } from "@vef-framework-react/core";

const result = useInfiniteQuery({
queryKey: [findUserPage.key, searchParams],
queryFn: findUserPage,
initialPageParam: 1,
getNextPageParam: (lastPage, pages) => pages.length + 1
});

useQueries

import { useQueries } from "@vef-framework-react/core";

const results = useQueries({
queries: [
{ queryKey: [findUserPage.key, params1], queryFn: findUserPage },
{ queryKey: [findRoleList.key], queryFn: findRoleList }
]
});

useMutationState

import { useMutationState } from "@vef-framework-react/core";

const states = useMutationState({
filters: { mutationKey: [createUser.key] }
});

useIsFetching and useIsMutating

useIsFetching(filters?: QueryFilters): number
useIsMutating(filters?: MutationFilters): number

Low-level hooks returning the count of currently fetching queries / running mutations that match the filters. In most cases, prefer useHasFetching and useHasMutating from @vef-framework-react/hooks which accept typed query/mutation keys and return a boolean.

useQueryClient

Returns the QueryClient provided by ApiClientProvider (which wraps children with TanStack's QueryClientProvider). Useful for cache operations (invalidateQueries, setQueryData, …) inside components; outside React, use apiClient[QUERY_CLIENT] instead.

useQueryErrorResetBoundary

TanStack's error-boundary reset hook, re-exported unchanged: returns { reset, clearReset, isReset } for coordinating query retries with an error boundary.

keepPreviousData

import { keepPreviousData } from "@vef-framework-react/core";

useQuery({
queryKey: [findUserPage.key, searchParams],
queryFn: findUserPage,
placeholderData: keepPreviousData
});

skipQueryToken

import { skipQueryToken } from "@vef-framework-react/core";

useQuery({
queryKey: [findUserPage.key, searchParams],
queryFn: searchParams ? findUserPage : skipQueryToken
});

matchQuery and matchMutation

Helpers for filtering queries and mutations in cache operations:

import { matchQuery, matchMutation } from "@vef-framework-react/core";

Type Exports

TypeDescription
UseQueryResult<TData>Result type of useQuery
DefinedUseQueryResult<TData>Result type when initial data is defined
UseQueryOptions<TQueryFnData, TData, TParams>Options for useQuery
DefinedInitialDataOptionsOptions when initial data is always defined
UndefinedInitialDataOptionsOptions when initial data may be undefined
UseInfiniteQueryOptionsOptions for useInfiniteQuery
UseMutationResult<TData, TParams>Result type of useMutation
QueryKeyHashFunctionCustom query key hash function type
PlaceholderDataFunctionType for placeholderData callback
RefetchOptionsOptions for refetch()
StaleTimeType for staleTime option
MutationMetaExtended mutation meta type
QueryMetaQuery meta type
SkipQueryTokenType of skipQueryToken (TanStack's SkipToken, renamed)
InitialDataFunction<T>Function form of initialData
MutationFunctionContextContext object passed to mutation functions
MutationScopeType of the scope mutation option (serial-execution scoping)
RetryValueboolean | number | ShouldRetryFunction — type of the retry option
ShouldRetryFunction(failureCount: number, error: Error) => boolean
RetryDelayValuenumber | RetryDelayFunction — type of the retryDelay option
RetryDelayFunction(failureCount: number, error: Error) => number

The VEF wrappers fix the error type to Error and the key type to QueryKey<TParams>, so useQuery / useMutation calls do not need to spell out TanStack's five-generic forms.