Hooks for managing, caching and syncing asynchronous and remote data in React
npx @tessl/cli install tessl/npm-react-query@4.0.0React Query is a powerful data-fetching and state management library for React applications that provides hooks for fetching, caching, synchronizing and updating asynchronous and remote data. It eliminates the need for complex state management patterns when dealing with server state by offering intelligent caching with automatic background updates, optimistic updates, request deduplication, and built-in error handling.
npm install react-queryimport { useQuery, useMutation, QueryClient, QueryClientProvider } from "react-query";For CommonJS:
const { useQuery, useMutation, QueryClient, QueryClientProvider } = require("react-query");import { useQuery, useMutation, QueryClient, QueryClientProvider } from "react-query";
// Create a query client
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<UserProfile userId="123" />
</QueryClientProvider>
);
}
function UserProfile({ userId }: { userId: string }) {
// Fetch user data
const { data: user, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetch(`/api/users/${userId}`).then(res => res.json())
});
// Create a mutation for updating user
const updateUser = useMutation({
mutationFn: (userData: any) =>
fetch(`/api/users/${userId}`, {
method: 'PUT',
body: JSON.stringify(userData)
}),
onSuccess: () => {
// Invalidate and refetch user data
queryClient.invalidateQueries({ queryKey: ['user', userId] });
}
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error loading user</div>;
return (
<div>
<h1>{user.name}</h1>
<button onClick={() => updateUser.mutate({ name: 'New Name' })}>
Update Name
</button>
</div>
);
}React Query is built around several key components:
useQuery, useMutation, etc.) providing reactive data fetching with automatic re-rendersCore data fetching functionality with intelligent caching, background updates, and automatic error handling. Perfect for loading data from APIs with automatic retry and stale-while-revalidate patterns.
function useQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(
options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>
): UseQueryResult<TData, TError>;
function useQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(
queryKey: TQueryKey,
queryFn: QueryFunction<TQueryFnData, TQueryKey>,
options?: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>
): UseQueryResult<TData, TError>;Specialized query hook for paginated data with infinite scrolling support, automatic page management, and cursor-based pagination.
function useInfiniteQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(
options: UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>
): UseInfiniteQueryResult<TData, TError>;
interface UseInfiniteQueryResult<TData = unknown, TError = unknown> {
data: InfiniteData<TData> | undefined;
fetchNextPage: () => Promise<any>;
fetchPreviousPage: () => Promise<any>;
hasNextPage: boolean;
hasPreviousPage: boolean;
isFetchingNextPage: boolean;
isFetchingPreviousPage: boolean;
}Execute multiple queries in parallel with type-safe results and coordinated loading states.
function useQueries<T extends any[]>({
queries,
context,
}: {
queries: readonly [...QueriesOptions<T>];
context?: React.Context<QueryClient | undefined>;
}): QueriesResults<T>;Data mutation operations with optimistic updates, automatic error handling, and cache invalidation patterns.
function useMutation<TData = unknown, TError = unknown, TVariables = void, TContext = unknown>(
options: UseMutationOptions<TData, TError, TVariables, TContext>
): UseMutationResult<TData, TError, TVariables, TContext>;
interface UseMutationResult<TData = unknown, TError = unknown, TVariables = unknown, TContext = unknown> {
mutate: (variables: TVariables, options?: MutateOptions<TData, TError, TVariables, TContext>) => void;
mutateAsync: (variables: TVariables, options?: MutateOptions<TData, TError, TVariables, TContext>) => Promise<TData>;
data: TData | undefined;
error: TError | null;
isError: boolean;
isPending: boolean;
isSuccess: boolean;
}QueryClient provider system for sharing client instances across component trees with context isolation and configuration.
function QueryClientProvider(props: QueryClientProviderProps): JSX.Element;
function useQueryClient(options?: ContextOptions): QueryClient;
interface QueryClientProviderProps {
client: QueryClient;
children?: React.ReactNode;
context?: React.Context<QueryClient | undefined>;
contextSharing?: boolean;
}Hooks for monitoring global query and mutation states across the application.
function useIsFetching(filters?: QueryFilters, options?: ContextOptions): number;
function useIsMutating(filters?: MutationFilters, options?: ContextOptions): number;Server-side rendering support with state dehydration and hydration for seamless SSR/SSG integration.
function useHydrate(state: unknown, options?: HydrateOptions & ContextOptions): void;
function Hydrate(props: HydrateProps): React.ReactElement;
function IsRestoringProvider(props: { value: boolean; children: React.ReactNode; }): React.ReactElement;
function useIsRestoring(): boolean;
interface HydrateProps {
state?: unknown;
options?: HydrateOptions;
children?: React.ReactNode;
}Error boundary integration and reset functionality for graceful error recovery.
function QueryErrorResetBoundary(props: QueryErrorResetBoundaryProps): JSX.Element;
function useQueryErrorResetBoundary(): QueryErrorResetBoundaryValue;
interface QueryErrorResetBoundaryValue {
clearReset: () => void;
isReset: () => boolean;
reset: () => void;
}type QueryKey = readonly unknown[];
type QueryFunction<T = unknown, TQueryKey extends QueryKey = QueryKey> = (
context: QueryFunctionContext<TQueryKey>
) => T | Promise<T>;
interface QueryFunctionContext<TQueryKey extends QueryKey = QueryKey> {
queryKey: TQueryKey;
signal?: AbortSignal;
pageParam?: unknown;
meta: QueryMeta | undefined;
}
interface UseQueryResult<TData = unknown, TError = unknown> {
data: TData | undefined;
error: TError | null;
isError: boolean;
isLoading: boolean;
isPending: boolean;
isSuccess: boolean;
isFetching: boolean;
isRefetching: boolean;
status: 'pending' | 'error' | 'success';
fetchStatus: 'fetching' | 'paused' | 'idle';
refetch: () => Promise<any>;
}
interface DefinedUseQueryResult<TData = unknown, TError = unknown> extends Omit<UseQueryResult<TData, TError>, 'data'> {
data: TData;
}
interface UseQueryOptions<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> {
queryKey?: TQueryKey;
queryFn?: QueryFunction<TQueryFnData, TQueryKey>;
enabled?: boolean;
retry?: boolean | number | ((failureCount: number, error: TError) => boolean);
retryDelay?: number | ((retryAttempt: number, error: TError) => number);
staleTime?: number;
cacheTime?: number;
refetchInterval?: number | false | ((data: TData | undefined, query: Query) => number | false);
refetchIntervalInBackground?: boolean;
refetchOnMount?: boolean | "always";
refetchOnWindowFocus?: boolean | "always";
refetchOnReconnect?: boolean | "always";
select?: (data: TQueryFnData) => TData;
initialData?: TData | (() => TData);
placeholderData?: TData | (() => TData);
onSuccess?: (data: TData) => void;
onError?: (error: TError) => void;
onSettled?: (data: TData | undefined, error: TError | null) => void;
context?: React.Context<QueryClient | undefined>;
}
interface InfiniteData<TData> {
pages: TData[];
pageParams: unknown[];
}
type QueryFilters = {
queryKey?: QueryKey;
exact?: boolean;
type?: 'active' | 'inactive' | 'all';
stale?: boolean;
fetching?: boolean;
};
type MutationFilters = {
mutationKey?: QueryKey;
exact?: boolean;
type?: 'active' | 'paused' | 'all';
};
interface ContextOptions {
context?: React.Context<QueryClient | undefined>;
}