SuspenseuseQuery ParametersAccessor<QueryOptions>queryKey: unknown[]queryFn: (context: QueryFunctionContext) => Promise<TData>enabled: booleanselect: (data: TData) => unknownplaceholderData: TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TDatadeferStream: booleanreconcile: false | string | ((oldData: TData | undefined, newData: TData) => TData)gcTime: number | InfinitynetworkMode: 'online' | 'always' | 'offlineFirst'initialData: TData | () => TDatainitialDataUpdatedAt: number | (() => number | undefined)meta: Record<string, unknown>queryKeyHashFn: (queryKey: QueryKey) => stringrefetchInterval: number | false | ((query: Query) => number | false | undefined)refetchIntervalInBackground: booleanrefetchOnMount: boolean | "always" | ((query: Query) => boolean | "always")refetchOnWindowFocus: boolean | "always" | ((query: Query) => boolean | "always")refetchOnReconnect: boolean | "always" | ((query: Query) => boolean | "always")retry: boolean | number | (failureCount: number, error: TError) => booleanretryOnMount: booleanretryDelay: number | (retryAttempt: number, error: TError) => numberstaleTime: number | InfinitythrowOnError: undefined | boolean | (error: TError, query: Query) => booleanAccessor<QueryClient>useQuery Return Value - Store<QueryResult<TData, TError>>status: QueryStatusisPending: booleanisSuccess: booleanisError: booleanisLoadingError: booleanisRefetchError: booleandata: Resource<TData>dataUpdatedAt: numbererror: null | TErrorerrorUpdatedAt: numberisStale: booleanisPlaceholderData: booleanisFetched: booleanisFetchedAfterMount: booleanfetchStatus: FetchStatusisFetching: booleanisPaused: booleanisRefetching: booleanisLoading: booleanisInitialLoading: booleanfailureCount: numberfailureReason: null | TErrorerrorUpdateCount: numberrefetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise<UseQueryResult>const {
data,
dataUpdatedAt,
error,
errorUpdatedAt,
failureCount,
failureReason,
fetchStatus,
isError,
isFetched,
isFetchedAfterMount,
isFetching,
isInitialLoading,
isLoading,
isLoadingError,
isPaused,
isPending,
isPlaceholderData,
isRefetchError,
isRefetching,
isStale,
isSuccess,
refetch,
status,
} = useQuery(
() => ({
queryKey,
queryFn,
enabled,
select,
placeholderData,
deferStream,
reconcile,
gcTime,
networkMode,
initialData,
initialDataUpdatedAt,
meta,
queryKeyHashFn,
refetchInterval,
refetchIntervalInBackground,
refetchOnMount,
refetchOnReconnect,
refetchOnWindowFocus,
retry,
retryOnMount,
retryDelay,
staleTime,
throwOnError,
}),
() => queryClient,
)
const {
data,
dataUpdatedAt,
error,
errorUpdatedAt,
failureCount,
failureReason,
fetchStatus,
isError,
isFetched,
isFetchedAfterMount,
isFetching,
isInitialLoading,
isLoading,
isLoadingError,
isPaused,
isPending,
isPlaceholderData,
isRefetchError,
isRefetching,
isStale,
isSuccess,
refetch,
status,
} = useQuery(
() => ({
queryKey,
queryFn,
enabled,
select,
placeholderData,
deferStream,
reconcile,
gcTime,
networkMode,
initialData,
initialDataUpdatedAt,
meta,
queryKeyHashFn,
refetchInterval,
refetchIntervalInBackground,
refetchOnMount,
refetchOnReconnect,
refetchOnWindowFocus,
retry,
retryOnMount,
retryDelay,
staleTime,
throwOnError,
}),
() => queryClient,
)
Here are some examples of how to use the useQuery primitive in Solid Query.
The most basic usage of useQuery is to create a query that fetches data from an API.
import { useQuery } from '@tanstack/solid-query'
function App() {
const todos = useQuery(() => ({
queryKey: 'todos',
queryFn: async () => {
const response = await fetch('/api/todos')
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
}))
return (
<div>
<Show when={todos.isError}>
<div>Error: {todos.error.message}</div>
</Show>
<Show when={todos.isLoading}>
<div>Loading...</div>
</Show>
<Show when={todos.isSuccess}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Show>
</div>
)
}
import { useQuery } from '@tanstack/solid-query'
function App() {
const todos = useQuery(() => ({
queryKey: 'todos',
queryFn: async () => {
const response = await fetch('/api/todos')
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
}))
return (
<div>
<Show when={todos.isError}>
<div>Error: {todos.error.message}</div>
</Show>
<Show when={todos.isLoading}>
<div>Loading...</div>
</Show>
<Show when={todos.isSuccess}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Show>
</div>
)
}
The reason why useQuery accepts a function that returns an object is to allow for reactive options. This is useful when query options depend on other values/signals that might change over time. Solid Query can track the passed function in a reactive scope and re-run it whenever the dependencies change.
import { useQuery } from '@tanstack/solid-query'
function App() {
const [filter, setFilter] = createSignal('all')
const todos = useQuery(() => ({
queryKey: ['todos', filter()],
queryFn: async () => {
const response = await fetch(`/api/todos?filter=${filter()}`)
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
}))
return (
<div>
<div>
<button onClick={() => setFilter('all')}>All</button>
<button onClick={() => setFilter('active')}>Active</button>
<button onClick={() => setFilter('completed')}>Completed</button>
</div>
<Show when={todos.isError}>
<div>Error: {todos.error.message}</div>
</Show>
<Show when={todos.isLoading}>
<div>Loading...</div>
</Show>
<Show when={todos.isSuccess}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Show>
</div>
)
}
import { useQuery } from '@tanstack/solid-query'
function App() {
const [filter, setFilter] = createSignal('all')
const todos = useQuery(() => ({
queryKey: ['todos', filter()],
queryFn: async () => {
const response = await fetch(`/api/todos?filter=${filter()}`)
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
}))
return (
<div>
<div>
<button onClick={() => setFilter('all')}>All</button>
<button onClick={() => setFilter('active')}>Active</button>
<button onClick={() => setFilter('completed')}>Completed</button>
</div>
<Show when={todos.isError}>
<div>Error: {todos.error.message}</div>
</Show>
<Show when={todos.isLoading}>
<div>Loading...</div>
</Show>
<Show when={todos.isSuccess}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Show>
</div>
)
}
useQuery supports triggering SolidJS Suspense and ErrorBoundary components when the query is in a pending or error state. This allows you to easily handle loading and error states in your components.
import { useQuery } from '@tanstack/solid-query'
function App() {
const todos = useQuery(() => ({
queryKey: 'todos',
queryFn: async () => {
const response = await fetch('/api/todos')
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
throwOnError: true,
}))
return (
<ErrorBoundary fallback={<div>Error: {todos.error.message}</div>}>
<Suspense fallback={<div>Loading...</div>}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Suspense>
</ErrorBoundary>
)
}
import { useQuery } from '@tanstack/solid-query'
function App() {
const todos = useQuery(() => ({
queryKey: 'todos',
queryFn: async () => {
const response = await fetch('/api/todos')
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
throwOnError: true,
}))
return (
<ErrorBoundary fallback={<div>Error: {todos.error.message}</div>}>
<Suspense fallback={<div>Loading...</div>}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Suspense>
</ErrorBoundary>
)
}
useQuery returns a SolidJS store with the following properties:
