Skip to main content
TanStack Query provides a collection of utility functions for common operations like key matching, data transformation, and query filtering.

Query and Mutation Matching

matchQuery

Determines if a query matches the given filters.
function matchQuery(
  filters: QueryFilters,
  query: Query<any, any, any, any>,
): boolean

Parameters

filters
QueryFilters
required
The filter criteria to match against.
type
'all' | 'active' | 'inactive'
default:"'all'"
Filter queries by their active state.
exact
boolean
If true, the query key must match exactly. If false, partial matching is used.
queryKey
QueryKey
The query key or key prefix to match.
stale
boolean
Filter queries by their stale state.
fetchStatus
'fetching' | 'paused' | 'idle'
Filter queries by their fetch status.
predicate
(query: Query) => boolean
Custom predicate function for advanced filtering.
query
Query
required
The query instance to test against the filters.

Returns

boolean - Returns true if the query matches all specified filters, false otherwise.

matchMutation

Determines if a mutation matches the given filters.
function matchMutation(
  filters: MutationFilters,
  mutation: Mutation<any, any>,
): boolean

Parameters

filters
MutationFilters
required
The filter criteria to match against.
exact
boolean
If true, the mutation key must match exactly. If false, partial matching is used.
mutationKey
MutationKey
The mutation key or key prefix to match.
status
'idle' | 'pending' | 'success' | 'error'
Filter mutations by their status.
predicate
(mutation: Mutation) => boolean
Custom predicate function for advanced filtering.
mutation
Mutation
required
The mutation instance to test against the filters.

Returns

boolean - Returns true if the mutation matches all specified filters, false otherwise.

Key Hashing and Matching

hashKey

Generates a stable hash from a query or mutation key.
function hashKey(queryKey: QueryKey | MutationKey): string

Parameters

queryKey
QueryKey | MutationKey
required
The key to hash. Can be any serializable array.

Returns

string - A stable JSON string representation of the key with object keys sorted.

Example

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

const hash1 = hashKey(['posts', { userId: 1, sort: 'desc' }])
const hash2 = hashKey(['posts', { sort: 'desc', userId: 1 }])

// Both produce the same hash due to key sorting
console.log(hash1 === hash2) // true
Object properties in the key are sorted alphabetically to ensure consistent hashing regardless of property order.

hashQueryKeyByOptions

Generates a query key hash using options-specific hash function if provided.
function hashQueryKeyByOptions<TQueryKey extends QueryKey = QueryKey>(
  queryKey: TQueryKey,
  options?: Pick<QueryOptions<any, any, any, any>, 'queryKeyHashFn'>,
): string

Parameters

queryKey
QueryKey
required
The query key to hash.
options
Pick<QueryOptions, 'queryKeyHashFn'>
Optional query options containing a custom hash function.

Returns

string - The hashed query key using the custom hash function if provided, or the default hashKey function.

partialMatchKey

Checks if key b partially matches with key a.
function partialMatchKey(a: QueryKey, b: QueryKey): boolean

Parameters

a
QueryKey
required
The full key to match against.
b
QueryKey
required
The partial key or key prefix to check.

Returns

boolean - Returns true if b is a partial match of a.

Example

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

partialMatchKey(
  ['posts', { userId: 1, status: 'published' }],
  ['posts', { userId: 1 }]
) // true

partialMatchKey(
  ['posts', { userId: 1 }],
  ['posts', { userId: 2 }]
) // false

Data Transformation

replaceEqualDeep

Performs deep equality checking and structural sharing between two values.
function replaceEqualDeep<T>(a: unknown, b: T, depth?: number): T

Parameters

a
unknown
required
The previous value to compare against.
b
T
required
The new value to compare and potentially share structure with.
depth
number
default:"0"
The current recursion depth. Stops recursion at depth 500 to prevent stack overflow.

Returns

T - Returns a if b is deeply equal, otherwise returns a new object/array with shared references for equal children.

Example

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

const oldData = { user: { id: 1, name: 'John' }, posts: [1, 2, 3] }
const newData = { user: { id: 1, name: 'John' }, posts: [1, 2, 3] }

const result = replaceEqualDeep(oldData, newData)

// result.user === oldData.user (same reference)
// result.posts === oldData.posts (same reference)
This function is used internally by TanStack Query for structural sharing, which helps prevent unnecessary re-renders by maintaining referential equality for unchanged data.

replaceData

Replaces query data with structural sharing based on options.
function replaceData<
  TData,
  TOptions extends QueryOptions<any, any, any, any>,
>(
  prevData: TData | undefined,
  data: TData,
  options: TOptions,
): TData

Parameters

prevData
TData | undefined
required
The previous data value.
data
TData
required
The new data value.
options
QueryOptions
required
Query options containing structuralSharing configuration.

Returns

TData - The new data, potentially with structural sharing applied.

keepPreviousData

Utility function that returns the previous data unchanged.
function keepPreviousData<T>(previousData: T | undefined): T | undefined

Parameters

previousData
T | undefined
required
The previous data value.

Returns

T | undefined - The same previous data value passed in.

Example

import { keepPreviousData } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'

function Component({ page }) {
  const { data } = useQuery({
    queryKey: ['posts', page],
    queryFn: () => fetchPosts(page),
    placeholderData: keepPreviousData,
  })
  
  // Previous page data is shown while new page loads
}

Object Comparison

shallowEqualObjects

Performs shallow equality comparison between two objects.
function shallowEqualObjects<T extends Record<string, any>>(
  a: T,
  b: T | undefined,
): boolean

Parameters

a
Record<string, any>
required
The first object to compare.
b
Record<string, any> | undefined
required
The second object to compare.

Returns

boolean - Returns true if objects have the same keys and values (using === comparison), false otherwise.

Type Guards

isPlainArray

Checks if a value is a plain array.
function isPlainArray(value: unknown): value is Array<unknown>

Returns

boolean - Returns true if the value is an array with only numeric indices.

isPlainObject

Checks if a value is a plain JavaScript object.
function isPlainObject(o: any): o is Record<PropertyKey, unknown>

Returns

boolean - Returns true if the value is a plain object created by {} or new Object(), false for class instances, arrays, null, etc.

isValidTimeout

Checks if a value is a valid timeout duration.
function isValidTimeout(value: unknown): value is number

Returns

boolean - Returns true if the value is a number >= 0 and not Infinity.

Time Utilities

timeUntilStale

Calculates the time in milliseconds until data becomes stale.
function timeUntilStale(updatedAt: number, staleTime?: number): number

Parameters

updatedAt
number
required
The timestamp when the data was last updated (in milliseconds).
staleTime
number
The stale time duration in milliseconds.

Returns

number - The number of milliseconds until the data becomes stale, or 0 if already stale.

resolveStaleTime

Resolves a stale time value, handling both static values and functions.
function resolveStaleTime<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
>(
  staleTime:
    | undefined
    | StaleTimeFunction<TQueryFnData, TError, TData, TQueryKey>,
  query: Query<TQueryFnData, TError, TData, TQueryKey>,
): StaleTime | undefined

Returns

number | 'static' | undefined - The resolved stale time value.

resolveEnabled

Resolves an enabled value, handling both static values and functions.
function resolveEnabled<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
>(
  enabled: undefined | Enabled<TQueryFnData, TError, TData, TQueryKey>,
  query: Query<TQueryFnData, TError, TData, TQueryKey>,
): boolean | undefined

Returns

boolean | undefined - The resolved enabled value.

sleep

Creates a promise that resolves after a specified timeout.
function sleep(timeout: number): Promise<void>

Parameters

timeout
number
required
The timeout duration in milliseconds.

Returns

Promise<void> - A promise that resolves after the specified timeout.

Array Utilities

addToEnd

Adds an item to the end of an array with optional maximum length.
function addToEnd<T>(items: Array<T>, item: T, max = 0): Array<T>

Parameters

items
Array<T>
required
The source array.
item
T
required
The item to add.
max
number
default:"0"
Maximum array length. If exceeded, items are removed from the start. Use 0 for no limit.

Returns

Array<T> - A new array with the item added to the end.

addToStart

Adds an item to the start of an array with optional maximum length.
function addToStart<T>(items: Array<T>, item: T, max = 0): Array<T>

Parameters

items
Array<T>
required
The source array.
item
T
required
The item to add.
max
number
default:"0"
Maximum array length. If exceeded, items are removed from the end. Use 0 for no limit.

Returns

Array<T> - A new array with the item added to the start.

Functional Utilities

functionalUpdate

Applies an updater that can be either a value or a function.
function functionalUpdate<TInput, TOutput>(
  updater: Updater<TInput, TOutput>,
  input: TInput,
): TOutput

Parameters

updater
TOutput | ((input: TInput) => TOutput)
required
Either a direct value or a function that takes the input and returns the output.
input
TInput
required
The input value to pass to the updater function.

Returns

TOutput - If updater is a function, returns the result of calling it with input. Otherwise, returns updater directly.

noop

A no-operation function that does nothing.
function noop(): void

Example

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

// Useful for avoiding unhandled promise rejections
promise.catch(noop)

ensureQueryFn

Ensures a valid query function exists or returns an appropriate fallback.
function ensureQueryFn<
  TQueryFnData = unknown,
  TQueryKey extends QueryKey = QueryKey,
>(
  options: {
    queryFn?: QueryFunction<TQueryFnData, TQueryKey> | SkipToken
    queryHash?: string
  },
  fetchOptions?: FetchOptions<TQueryFnData>,
): QueryFunction<TQueryFnData, TQueryKey>

Returns

QueryFunction - A valid query function, or a function that returns a rejected promise if no valid function is available.

shouldThrowError

Determines if an error should be thrown based on configuration.
function shouldThrowError<T extends (...args: Array<any>) => boolean>(
  throwOnError: boolean | T | undefined,
  params: Parameters<T>,
): boolean

Parameters

throwOnError
boolean | Function | undefined
required
Can be a boolean, a function, or undefined.
params
Array<any>
required
Parameters to pass to the function if throwOnError is a function.

Returns

boolean - Returns true if errors should be thrown.

Constants

skipToken

A special symbol used to skip query execution.
const skipToken: unique symbol
type SkipToken = typeof skipToken

Example

import { useQuery, skipToken } from '@tanstack/react-query'

function Component({ userId }: { userId?: string }) {
  const { data } = useQuery({
    queryKey: ['user', userId],
    queryFn: userId ? () => fetchUser(userId) : skipToken,
  })
  
  // Query is skipped when userId is undefined
}

isServer

Boolean indicating if the code is running in a server environment.
const isServer: boolean
Returns true if window is undefined or Deno is detected in global scope.

TypeScript Types

QueryFilters

interface QueryFilters<TQueryKey extends QueryKey = QueryKey> {
  type?: 'all' | 'active' | 'inactive'
  exact?: boolean
  predicate?: (query: Query) => boolean
  queryKey?: TQueryKey
  stale?: boolean
  fetchStatus?: 'fetching' | 'paused' | 'idle'
}

MutationFilters

interface MutationFilters<
  TData = unknown,
  TError = DefaultError,
  TVariables = unknown,
  TOnMutateResult = unknown,
> {
  exact?: boolean
  predicate?: (mutation: Mutation<TData, TError, TVariables, TOnMutateResult>) => boolean
  mutationKey?: MutationKey
  status?: 'idle' | 'pending' | 'success' | 'error'
}

Updater

type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput)

Build docs developers (and LLMs) love