useQuery is an auto-generated hook that automatically triggers data fetching, subscribes your component to cached data, and re-renders as the loading status changes.
Overview
The hook is generated from your API definition using createApi. For an endpoint named getPosts, the generated hook will be useGetPostsQuery.
export const postsApi = createApi ({
baseQuery: fetchBaseQuery ({ baseUrl: '/api' }),
endpoints : ( build ) => ({
getPosts: build . query < Post [], void >({
query : () => '/posts' ,
}),
}),
});
export const { useGetPostsQuery } = postsApi ;
Signature
const result = useXxxQuery ( arg , options ? );
arg
QueryArg | Signal<QueryArg> | (() => QueryArg | SkipToken)
required
The argument to pass to the query function. Can be:
A static value
A signal
A function returning a value or skipToken
Optional configuration object or signal: Skip this query execution if true
Refetch interval in milliseconds. Set to 0 to disable polling
Skip polling when window is unfocused
Refetch when network connection is restored
Refetch when window regains focus
refetchOnMountOrArgChange
Refetch on mount or when arg changes. If number, minimum time in seconds between refetches
Select a subset of the result for fine-grained reactivity
Return Value
Returns a signal object with query state and methods:
data
Signal<ResultType | undefined>
The returned data from the query. Access with result.data() for fine-grained reactivity
true if the query is loading for the first time (no data yet)
true if the query is currently fetching
true if the query has succeeded
true if the query has errored
error
Signal<Error | undefined>
The error object if the query failed
Function to manually refetch the data
Usage Examples
Basic Usage
import { useGetPostsQuery } from './api' ;
@ Component ({
selector: 'app-posts' ,
template: `
@if (postsQuery.isLoading()) {
<p>Loading...</p>
}
@if (postsQuery.isError()) {
<p>Error: {{ postsQuery.error() }}</p>
}
@if (postsQuery.data(); as posts) {
@for (post of posts; track post.id) {
<div>{{ post.title }}</div>
}
}
` ,
})
export class PostsComponent {
postsQuery = useGetPostsQuery ();
}
With Signal Parameters
export class PostDetailsComponent {
postId = input . required < number >();
postQuery = useGetPostQuery ( this . postId );
}
With Function Parameters
export class PostDetailsComponent {
postId = signal ( 1 );
postQuery = useGetPostQuery (() => this . postId ());
}
With skipToken
import { skipToken } from 'ngrx-rtk-query' ;
export class PostDetailsComponent {
postId = input < number | undefined >();
// Only fetch when postId is defined
postQuery = useGetPostQuery (
() => this . postId () ?? skipToken
);
}
With Options
export class PostDetailsComponent {
postId = input . required < number >();
postQuery = useGetPostQuery ( this . postId , {
pollingInterval: 5000 , // Refetch every 5 seconds
refetchOnFocus: true ,
});
}
With selectFromResult
export class PostTitleComponent {
postId = input . required < number >();
// Only subscribe to title changes
postQuery = useGetPostQuery ( this . postId , {
selectFromResult : ({ data , isLoading }) => ({
title: data ?. title ,
isLoading ,
}),
});
}
Fine-Grained vs Coarse-Grained Reactivity
// Fine-grained: Only re-renders when isLoading changes
{{ postsQuery . isLoading () }}
// Coarse-grained: Re-renders when any property changes
{{ postsQuery (). isLoading }}
Use fine-grained reactivity (query.property()) for better performance. Only use coarse-grained (query().property) when you need multiple properties at once.
See Also