react-query
Version:
Hooks for managing, caching and syncing asynchronous and remote data in React
695 lines (620 loc) • 19.7 kB
TypeScript
// Definitions by: Lukasz Fiszer <https://github.com/lukaszfiszer>
// Jace Hensley <https://github.com/jacehensley>
// Matteo Frana <https://github.com/matteofrana>
// Igor Oleinikov <https://github.com/igorbek>
// Minimum TypeScript Version: 3.9
import * as React from 'react'
import * as _ from 'ts-toolbelt'
// overloaded useQuery function
export type UseQueryRest<TResult, TKey extends AnyQueryKey, TError> =
| []
| [QueryFunction<TResult, TKey>]
| [QueryFunction<TResult, TKey>, QueryOptions<TResult, TError> | undefined]
| [QueryOptions<TResult, TError>]
// Object Syntax
export function useQuery<TResult, TKey extends AnyQueryKey, TError = Error>({
queryKey,
queryFn,
config,
}: {
queryKey: TKey
queryFn?: QueryFunction<TResult, TKey>
config?: QueryOptions<TResult, TError>
}): QueryResult<TResult, TError>
export function useQuery<TResult, TKey extends string, TError = Error>({
queryKey,
queryFn,
config,
}: {
queryKey: TKey
queryFn?: QueryFunction<TResult, [TKey]>
config?: QueryOptions<TResult, TError>
}): QueryResult<TResult, TError>
// Parameters Syntax
export function useQuery<TResult, TKey extends AnyQueryKey, TError = Error>(
queryKey: TKey | false | null | undefined,
...rest: UseQueryRest<TResult, TKey, TError>
): QueryResult<TResult, TError>
export function useQuery<TResult, TKey extends string, TError = Error>(
queryKey: TKey | false | null | undefined,
...rest: UseQueryRest<TResult, [TKey], TError>
): QueryResult<TResult, TError>
// usePaginatedQuery
export function usePaginatedQuery<
TResult,
TKey extends AnyQueryKey,
TError = Error
>({
queryKey,
queryFn,
config,
}: {
queryKey: TKey | false | null | undefined
queryFn: QueryFunction<TResult, TKey>
config?: QueryOptions<TResult, TError>
}): PaginatedQueryResult<TResult, TError>
export function usePaginatedQuery<
TResult,
TSingleKey extends string,
TError = Error
>({
queryKey,
queryFn,
config,
}: {
queryKey: TSingleKey | false | null | undefined
queryFn: QueryFunction<TResult, [TSingleKey]>
config?: QueryOptions<TResult, TError>
}): PaginatedQueryResult<TResult, TError>
export function usePaginatedQuery<
TResult,
TKey extends AnyQueryKey,
TError = Error
>(
queryKey: TKey | false | null | undefined,
queryFn: QueryFunction<TResult, TKey>,
config?: QueryOptions<TResult, TError>
): PaginatedQueryResult<TResult, TError>
export function usePaginatedQuery<TResult, TKey extends string, TError = Error>(
queryKey: TKey | false | null | undefined,
queryFn: QueryFunction<TResult, [TKey]>,
config?: QueryOptions<TResult, TError>
): PaginatedQueryResult<TResult, TError>
export function usePaginatedQuery<
TResult,
TKey extends AnyQueryKey,
TError = Error
>(
queryKey: TKey | false | null | undefined,
queryFn: QueryFunction<TResult, TKey>,
config?: QueryOptions<TResult, TError>
): PaginatedQueryResult<TResult, TError>
export function usePaginatedQuery<TResult, TKey extends string, TError = Error>(
queryKey: TKey | false | null | undefined,
queryFn: QueryFunction<TResult, [TKey]>,
config?: QueryOptions<TResult, TError>
): PaginatedQueryResult<TResult, TError>
// useInfiniteQuery
export type InfiniteQueryKey<T> = T | false | null | undefined
export function useInfiniteQuery<
TResult,
TKey extends AnyQueryKey,
TMoreVariable,
TError = Error
>({
queryKey,
queryFn,
config,
}: {
queryKey: InfiniteQueryKey<TKey>
queryFn?: InfiniteQueryFunction<TResult, TKey, TMoreVariable>
config?: InfiniteQueryOptions<TResult, TMoreVariable, TError>
}): InfiniteQueryResult<TResult, TMoreVariable, TError>
export function useInfiniteQuery<
TResult,
TSingleKey extends string,
TMoreVariable,
TError = Error
>({
queryKey,
queryFn,
config,
}: {
queryKey: InfiniteQueryKey<TSingleKey>
queryFn?: InfiniteQueryFunction<TResult, [TSingleKey], TMoreVariable>
config?: InfiniteQueryOptions<TResult, TMoreVariable, TError>
}): InfiniteQueryResult<TResult, TMoreVariable, TError>
export function useInfiniteQuery<
TResult,
TKey extends AnyQueryKey,
TMoreVariable,
TError = Error
>(
queryKey: InfiniteQueryKey<TKey>,
queryFn: InfiniteQueryFunction<TResult, TKey, TMoreVariable>,
config?: InfiniteQueryOptions<TResult, TMoreVariable, TError>
): InfiniteQueryResult<TResult, TMoreVariable, TError>
export function useInfiniteQuery<
TResult,
TKey extends string,
TMoreVariable,
TError = Error
>(
queryKey: InfiniteQueryKey<TKey>,
queryFn: InfiniteQueryFunction<TResult, [TKey], TMoreVariable>,
config?: InfiniteQueryOptions<TResult, TMoreVariable, TError>
): InfiniteQueryResult<TResult, TMoreVariable, TError>
export function useInfiniteQuery<
TResult,
TKey extends AnyQueryKey,
TMoreVariable,
TError = Error
>(
queryKey: InfiniteQueryKey<TKey>,
queryFn: InfiniteQueryFunction<TResult, TKey, TMoreVariable>,
config?: InfiniteQueryOptions<TResult, TMoreVariable, TError>
): InfiniteQueryResult<TResult, TMoreVariable, TError>
export function useInfiniteQuery<
TResult,
TKey extends string,
TMoreVariable,
TError = Error
>(
queryKey: InfiniteQueryKey<TKey>,
queryFn: InfiniteQueryFunction<TResult, [TKey], TMoreVariable>,
config?: InfiniteQueryOptions<TResult, TMoreVariable, TError>
): InfiniteQueryResult<TResult, TMoreVariable, TError>
export type DefinedQueryKeyPart =
| string
| object
| boolean
| number
| readonly QueryKeyPart[]
export type QueryKeyPart =
| string
| object
| boolean
| number
| readonly QueryKeyPart[]
| null
| undefined
export type AnyQueryKey = readonly [DefinedQueryKeyPart, ...QueryKeyPart[]] // this forces the key to be inferred as a tuple
export type QueryFunction<TResult, TKey extends AnyQueryKey> = (
...key: Readonly<TKey>
) => Promise<TResult>
export type InfiniteQueryFunction<
TResult,
TKey extends AnyQueryKey,
TMoreVariable
> = (
...keysAndMore: _.List.Append<TKey, TMoreVariable> | TKey
) => Promise<TResult>
export interface BaseSharedOptions {
suspense: boolean
}
export interface BaseQueryOptions<TResult = unknown, TError = Error> {
/**
* Set this to `false` to disable automatic refetching when the query mounts or changes query keys.
* To refetch the query, use the `refetch` method returned from the `useQuery` instance.
*/
enabled?: boolean | unknown
/**
* If `false`, failed queries will not retry by default.
* If `true`, failed queries will retry infinitely., failureCount: num
* If set to an integer number, e.g. 3, failed queries will retry until the failed query count meets that number.
* If set to a function `(failureCount, error) => boolean` failed queries will retry until the function returns false.
*/
retry?: boolean | number | ((failureCount: number, error: TError) => boolean)
retryDelay?: (retryAttempt: number) => number
staleTime?: number
cacheTime?: number
refetchInterval?: false | number
refetchIntervalInBackground?: boolean
refetchOnWindowFocus?: boolean
refetchOnMount?: boolean
onSuccess?: (data: TResult) => void
onError?: (err: TError) => void
onSettled?: (data: TResult | undefined, error: TError | null) => void
isDataEqual?: (oldData: unknown, newData: unknown) => boolean
useErrorBoundary?: boolean
queryFnParamsFilter?: (args: any[]) => any[]
}
export interface QueryOptions<TResult, TError = Error>
extends BaseQueryOptions<TResult, TError> {
suspense?: boolean
initialData?: TResult | (() => TResult | undefined)
initialStale?: boolean | (() => boolean | undefined)
}
export interface PrefetchQueryOptions {
force?: boolean
throwOnError?: boolean
}
export interface SetQueryDataQueryOptions<TResult, TError = Error>
extends QueryOptions<TResult, TError> {
exact?: boolean
}
export interface InfiniteQueryOptions<TResult, TMoreVariable, TError = Error>
extends QueryOptions<TResult[], TError> {
getFetchMore: (
lastPage: TResult,
allPages: TResult[]
) => TMoreVariable | false
}
export type QueryStatus = 'idle' | 'loading' | 'error' | 'success'
export interface QueryResultBase<TResult, TError = Error> {
status: QueryStatus
error: null | TError
isLoading: boolean
isSuccess: boolean
isError: boolean
isFetching: boolean
isStale: boolean
failureCount: number
canFetchMore?: boolean
markedForGarbageCollection: boolean
query: object
updatedAt: number
refetch: ({ throwOnError }?: { throwOnError?: boolean }) => Promise<TResult>
clear: () => void
}
export interface QueryIdleResult<TResult, TError = Error>
extends QueryResultBase<TResult, TError> {
status: 'idle'
isIdle: true
isLoading: false
isSuccess: false
isError: false
data: undefined
error: null
}
export interface QueryLoadingResult<TResult, TError = Error>
extends QueryResultBase<TResult, TError> {
status: 'loading'
isIdle: false
isLoading: true
isSuccess: false
isError: false
data: TResult | undefined // even when error, data can have stale data
error: TError | null // it still can be error
}
export interface QueryErrorResult<TResult, TError = Error>
extends QueryResultBase<TResult, TError> {
status: 'error'
isIdle: false
isError: true
isLoading: false
isSuccess: false
data: TResult | undefined // even when error, data can have stale data
error: TError
}
export interface QuerySuccessResult<TResult> extends QueryResultBase<TResult> {
status: 'success'
isIdle: false
isSuccess: true
isLoading: false
isError: false
data: TResult
error: null
}
export type QueryResult<TResult, TError = Error> =
| QueryIdleResult<TResult, TError>
| QueryLoadingResult<TResult, TError>
| QueryErrorResult<TResult, TError>
| QuerySuccessResult<TResult>
export interface PaginatedQueryLoadingResult<TResult, TError = Error>
extends QueryResultBase<TResult, TError> {
status: 'loading'
isLoading: true
isError: false
isSuccess: false
resolvedData: undefined | TResult // even when error, data can have stale data
latestData: undefined | TResult // even when error, data can have stale data
error: null | TError // it still can be error
}
export interface PaginatedQueryErrorResult<TResult, TError = Error>
extends QueryResultBase<TResult, TError> {
status: 'error'
isError: true
isLoading: false
isSuccess: false
resolvedData: undefined | TResult // even when error, data can have stale data
latestData: undefined | TResult // even when error, data can have stale data
error: TError
}
export interface PaginatedQuerySuccessResult<TResult>
extends QueryResultBase<TResult> {
status: 'success'
isSuccess: true
isError: false
isLoading: false
resolvedData: TResult
latestData: TResult
error: null
}
export type PaginatedQueryResult<TResult, TError = Error> =
| PaginatedQueryLoadingResult<TResult, TError>
| PaginatedQueryErrorResult<TResult, TError>
| PaginatedQuerySuccessResult<TResult>
export interface InfiniteQueryResult<TResult, TMoreVariable, TError = Error>
extends QueryResultBase<TResult[], TError> {
data: TResult[] | undefined
isFetchingMore: false | 'previous' | 'next'
canFetchMore: boolean | undefined
fetchMore: (
moreVariable?: TMoreVariable | false,
options?: { previous: boolean }
) => Promise<TResult[]> | undefined
}
export function useMutation<
TResult,
TVariables = undefined,
TError = Error,
TSnapshot = unknown
>(
mutationFn: MutationFunction<TResult, TVariables, TError, TSnapshot>,
mutationOptions?: MutationOptions<TResult, TVariables, TError, TSnapshot>
): MutationResultPair<TResult, TVariables, TError>
export type MutationResultPair<TResult, TVariables, TError> = [
MutateFunction<TResult, TVariables, TError>,
MutationResult<TResult, TError>
]
export type MutationFunction<
TResult,
TVariables,
TError = Error,
TSnapshot = unknown
> = (
variables: TVariables,
mutateOptions?: MutateOptions<TResult, TVariables, TError, TSnapshot>
) => Promise<TResult>
export interface MutateOptions<
TResult,
TVariables,
TError = Error,
TSnapshot = unknown
> {
onSuccess?: (data: TResult, variables: TVariables) => Promise<void> | void
onError?: (
error: TError,
variables: TVariables,
snapshotValue: TSnapshot
) => Promise<void> | void
onSettled?: (
data: undefined | TResult,
error: TError | null,
variables: TVariables,
snapshotValue?: TSnapshot
) => Promise<void> | void
throwOnError?: boolean
}
export interface MutationOptions<
TResult,
TVariables,
TError = Error,
TSnapshot = unknown
> extends MutateOptions<TResult, TVariables, TError, TSnapshot> {
onMutate?: (variables: TVariables) => Promise<TSnapshot> | TSnapshot
useErrorBoundary?: boolean
}
export type MutateFunction<
TResult,
TVariables,
TError = Error
> = TVariables extends undefined
? (options?: MutateOptions<TResult, TVariables, TError>) => Promise<TResult>
: (
variables: TVariables,
options?: MutateOptions<TResult, TVariables, TError>
) => Promise<TResult>
export interface MutationResultBase<TResult, TError = Error> {
status: 'idle' | 'loading' | 'error' | 'success'
data: undefined | TResult
error: undefined | null | TError
isIdle: boolean
isLoading: boolean
isSuccess: boolean
isError: boolean
reset: () => void
}
export interface IdleMutationResult<TResult, TError = Error>
extends MutationResultBase<TResult, TError> {
status: 'idle'
data: undefined
error: null
isIdle: true
isLoading: false
isSuccess: false
isError: false
}
export interface LoadingMutationResult<TResult, TError = Error>
extends MutationResultBase<TResult, TError> {
status: 'loading'
data: undefined
error: undefined
isIdle: false
isLoading: true
isSuccess: false
isError: false
}
export interface ErrorMutationResult<TResult, TError = Error>
extends MutationResultBase<TResult, TError> {
status: 'error'
data: undefined
error: TError
isIdle: false
isLoading: false
isSuccess: false
isError: true
}
export interface SuccessMutationResult<TResult>
extends MutationResultBase<TResult> {
status: 'success'
data: TResult
error: undefined
isIdle: false
isLoading: false
isSuccess: true
isError: false
}
export type MutationResult<TResult, TError = Error> =
| IdleMutationResult<TResult, TError>
| LoadingMutationResult<TResult, TError>
| ErrorMutationResult<TResult, TError>
| SuccessMutationResult<TResult>
export interface CachedQueryState<T, TError = Error> {
data?: T
error?: TError | null
failureCount: number
isFetching: boolean
canFetchMore?: boolean
isStale: boolean
status: 'loading' | 'error' | 'success'
updatedAt: number
}
export interface CachedQuery<T, TError = unknown> {
queryKey: AnyQueryKey
queryFn: (...args: any[]) => unknown
config: QueryOptions<unknown, TError>
state: CachedQueryState<T, TError>
setData(
dataOrUpdater:
| unknown
| undefined
| ((oldData: unknown | undefined) => unknown | undefined)
): void
clear(): void
}
export type QueryKey<TKey> = TKey | false | null | undefined
export type QueryKeyOrPredicateFn =
| AnyQueryKey
| string
| boolean
| ((query: CachedQuery<unknown>) => boolean)
export interface QueryCache {
prefetchQuery<TResult, TKey extends AnyQueryKey, TError = Error>(
queryKey: QueryKey<TKey>,
queryFn: QueryFunction<TResult, TKey>,
config?: QueryOptions<TResult, TError>,
prefetch?: PrefetchQueryOptions
): Promise<TResult>
prefetchQuery<TResult, TKey extends string, TError = Error>(
queryKey: QueryKey<TKey>,
queryFn: QueryFunction<TResult, [TKey]>,
config?: QueryOptions<TResult, TError>,
prefetch?: PrefetchQueryOptions
): Promise<TResult>
prefetchQuery<TResult, TKey extends AnyQueryKey, TError = Error>(
queryKey: QueryKey<TKey>,
queryFn: QueryFunction<TResult, TKey>,
prefetch?: PrefetchQueryOptions,
config?: QueryOptions<TResult, TError>
): Promise<TResult>
prefetchQuery<TResult, TKey extends string, TError = Error>(
queryKey: QueryKey<TKey>,
queryFn: QueryFunction<TResult, [TKey]>,
prefetch?: PrefetchQueryOptions,
config?: QueryOptions<TResult, TError>
): Promise<TResult>
prefetchQuery<TResult, TKey extends AnyQueryKey, TError = Error>({
queryKey,
queryFn,
config,
}: {
queryKey: QueryKey<TKey>
queryFn: QueryFunction<TResult, TKey>
config?: QueryOptions<TResult, TError>
prefetch?: PrefetchQueryOptions
}): Promise<TResult>
getQueryData<T = unknown>(key: QueryKeyOrPredicateFn): T | undefined
setQueryData<TResult, TError = Error>(
queryKeyOrPredicateFn: QueryKeyOrPredicateFn,
dataOrUpdater:
| TResult
| undefined
| ((oldData: TResult | undefined) => TResult | undefined),
config?: SetQueryDataQueryOptions<TResult, TError>
): void
invalidateQueries<TResult>(
queryKeyOrPredicateFn: QueryKeyOrPredicateFn,
{
exact,
throwOnError,
refetchActive,
refetchInactive,
}?: {
exact?: boolean
throwOnError?: boolean
refetchActive?: boolean
refetchInactive?: boolean
}
): Promise<TResult>
removeQueries(
queryKeyOrPredicateFn: QueryKeyOrPredicateFn,
{ exact }?: { exact?: boolean }
): void
getQuery(
queryKeyOrPredicateFn: QueryKeyOrPredicateFn
): CachedQuery<unknown> | undefined
getQueries(
queryKeyOrPredicateFn: QueryKeyOrPredicateFn,
{ exact }?: { exact?: boolean }
): Array<CachedQuery<unknown>>
cancelQueries(
queryKeyOrPredicateFn: QueryKeyOrPredicateFn,
{ exact }?: { exact?: boolean }
): void
isFetching: number
subscribe(callback: (queryCache: QueryCache, query?: CachedQuery<unknown>) => void): () => void
clear(options?: { notify?: boolean }): void
resetErrorBoundaries: () => void
}
export const queryCache: QueryCache
export const queryCaches: QueryCache[]
export interface MakeQueryCacheOptions<TError = Error> {
frozen?: boolean
defaultConfig?: ReactQueryProviderConfig<TError>
}
/**
* a factory that creates a new query cache
*/
export function makeQueryCache<TError = Error>(
makeQueryCacheOptions?: MakeQueryCacheOptions<TError>
): QueryCache
/**
* A hook that uses the query cache context
*/
export function useQueryCache(): QueryCache
export const ReactQueryCacheProvider: React.ComponentType<{
queryCache?: QueryCache
}>
/**
* A hook that returns the number of the queries that your application is loading or fetching in the background
* (useful for app-wide loading indicators).
* @returns the number of the queries that your application is currently loading or fetching in the background.
*/
export function useIsFetching(): number
export function ReactQueryConfigProvider<TError = Error>(props: {
config?: ReactQueryProviderConfig<TError>
children?: React.ReactNode
}): React.ReactElement
export interface ReactQueryProviderConfig<TError = Error> {
queries?: BaseQueryOptions<unknown, TError> & {
/** Defaults to the value of `suspense` if not defined otherwise */
useErrorBoundary?: boolean
refetchOnWindowFocus?: boolean
queryFn?: QueryFunction<unknown, AnyQueryKey>
queryKeySerializerFn?: (
queryKey: QueryKeyPart[] | string | false | undefined
) => [string, QueryKeyPart[]] | []
}
shared?: BaseSharedOptions
mutations?: MutationOptions<unknown, unknown, TError>
}
export type ConsoleFunction = (...args: any[]) => void
export interface ConsoleObject {
log: ConsoleFunction
warn: ConsoleFunction
error: ConsoleFunction
}
export function setConsole(consoleObject: ConsoleObject): void
export function deepIncludes(haystack: unknown, needle: unknown): boolean