TanStack
API Reference

useQuery

Overview

ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): UseQueryResult<TData, TError>;
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): DefinedUseQueryResult<TData, TError>;
  • UndefinedInitialDataOptions → UseQueryResult: Subscribes to a query: a declarative dependency on an asynchronous source of data that is tied to a unique key. The query runs when the options call for it — enabled: false skips the initial fetch.
  • DefinedInitialDataOptions → DefinedUseQueryResult: Subscribes to a query: a declarative dependency on an asynchronous source of data that is tied to a unique key. The query runs when the options call for it — enabled: false skips the initial fetch.

See also: Parameters · Returns

Call Signature

ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): UseQueryResult<TData, TError>;

Defined in: packages/solid-query/src/useQuery.ts:178

Subscribes to a query: a declarative dependency on an asynchronous source of data that is tied to a unique key. The query runs when the options call for it — enabled: false skips the initial fetch.

Type Parameters

TQueryFnData

TQueryFnData = unknown

TError

TError = Error

TData

TData = TQueryFnData

TQueryKey

TQueryKey extends readonly unknown[] = readonly unknown[]

Parameters

options

UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>

An accessor returning the UndefinedInitialDataOptions to use — everything you can pass to useQuery.

queryClient?

() => QueryClient

An accessor for a custom QueryClient. Otherwise, the one from the nearest context will be used.

Returns

UseQueryResult<TData, TError>

The current query result, as a Solid store. status is pending if there is no cached data to display, error if the last fetch attempt failed, or success if the query has data to display. isPending/isSuccess/isError are derived booleans for convenience.

See

queryOptions to share these options between useQuery and imperative APIs like queryClient.query.

Examples

tsx
import { For, Match, Switch } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'

function Posts() {
  const postsQuery = useQuery(() => ({
    queryKey: ['posts'],
    queryFn: fetchPosts,
  }))

  return (
    <Switch>
      <Match when={postsQuery.isPending}>Loading...</Match>
      <Match when={postsQuery.isError}>Error: {postsQuery.error.message}</Match>
      <Match when={postsQuery.isSuccess}>
        <ul>
          <For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>
        </ul>
        <div>{postsQuery.isFetching ? 'Background Updating...' : ' '}</div>
      </Match>
    </Switch>
  )
}

select derives whatever data a component needs from the cached value, without changing what's actually stored in the cache — the cache still holds the full Post[], but data here is a number:

tsx
import { Match, Switch } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'

function PostCount() {
  const postsQuery = useQuery(() => ({
    queryKey: ['posts'],
    queryFn: fetchPosts,
    select: (posts) => posts.length,
  }))

  return (
    <Switch>
      <Match when={postsQuery.isPending}>Loading...</Match>
      <Match when={postsQuery.isError}>Error: {postsQuery.error.message}</Match>
      <Match when={postsQuery.isSuccess}>{postsQuery.data} posts</Match>
    </Switch>
  )
}

A dependent query, only enabled once postId is set:

tsx
import { Match, Switch } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'

function Post(props: { postId: number | undefined }) {
  const postQuery = useQuery(() => ({
    queryKey: ['post', props.postId],
    queryFn: () => fetchPost(props.postId!),
    enabled: props.postId != null,
  }))

  return (
    <Switch fallback={<h1>{postQuery.data?.title}</h1>}>
      <Match when={props.postId == null}>Select a post</Match>
      <Match when={postQuery.isLoading}>Loading...</Match>
      <Match when={postQuery.isError}>Error: {postQuery.error.message}</Match>
    </Switch>
  )
}

The same dependent query, using skipToken to disable it in a type-safe way instead of relying on enabled. The non-null assertion is still needed — Solid's props narrowing doesn't survive into the queryFn closure the way a local const would — but skipToken keeps queryFn's return type accurate without it. refetch doesn't work while queryFn is skipToken — use enabled: false instead if you need to trigger the query manually:

tsx
import { Match, Switch } from 'solid-js'
import { skipToken, useQuery } from '@tanstack/solid-query'

function Post(props: { postId: number | undefined }) {
  const postQuery = useQuery(() => ({
    queryKey: ['post', props.postId],
    queryFn: props.postId != null ? () => fetchPost(props.postId!) : skipToken,
  }))

  return (
    <Switch fallback={<h1>{postQuery.data?.title}</h1>}>
      <Match when={props.postId == null}>Select a post</Match>
      <Match when={postQuery.isLoading}>Loading...</Match>
      <Match when={postQuery.isError}>Error: {postQuery.error.message}</Match>
    </Switch>
  )
}

Seeding a detail query from an already-cached list, to skip the loading state. initialDataUpdatedAt carries over the list's own fetch time, so that if you set a staleTime, it's measured from when the list was fetched rather than from now:

tsx
import { useQuery, useQueryClient } from '@tanstack/solid-query'

function Post(props: { postId: number }) {
  const queryClient = useQueryClient()

  const postQuery = useQuery(() => ({
    queryKey: ['post', props.postId],
    queryFn: () => fetchPost(props.postId),
    initialData: () =>
      queryClient
        .getQueryData<Array<Post>>(['posts'])
        ?.find((post) => post.id === props.postId),
    initialDataUpdatedAt: () =>
      queryClient.getQueryState(['posts'])?.dataUpdatedAt,
  }))

  return postQuery.isError ? <span>Error: {postQuery.error.message}</span> : <h1>{postQuery.data?.title}</h1>
}

Paginated data, keeping the previous page's data visible while the next page loads:

tsx
import { For, createSignal } from 'solid-js'
import { keepPreviousData, useQuery } from '@tanstack/solid-query'

function Posts() {
  const [page, setPage] = createSignal(0)

  const postsQuery = useQuery(() => ({
    queryKey: ['posts', page()],
    queryFn: () => fetchPosts(page()),
    placeholderData: keepPreviousData,
  }))

  return (
    <div>
      <ul>
        <For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>
      </ul>
      <button
        disabled={postsQuery.isPlaceholderData}
        onClick={() => setPage((old) => old + 1)}
      >
        Next Page
      </button>
    </div>
  )
}

Call Signature

ts
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): DefinedUseQueryResult<TData, TError>;

Defined in: packages/solid-query/src/useQuery.ts:228

Subscribes to a query: a declarative dependency on an asynchronous source of data that is tied to a unique key. The query runs when the options call for it — enabled: false skips the initial fetch.

This overload is selected when initialData is set, so the resulting data is never undefined (unless a select changes TData to include undefined).

Type Parameters

TQueryFnData

TQueryFnData = unknown

TError

TError = Error

TData

TData = TQueryFnData

TQueryKey

TQueryKey extends readonly unknown[] = readonly unknown[]

Parameters

options

DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>

An accessor returning the DefinedInitialDataOptions to use — everything you can pass to useQuery, with initialData set.

queryClient?

() => QueryClient

An accessor for a custom QueryClient. Otherwise, the one from the nearest context will be used.

Returns

DefinedUseQueryResult<TData, TError>

The current query result, as a Solid store, typed so that status is success — or error if a fetch attempt fails while keeping the existing data (status never resolves to pending in this overload's type, since initialData guarantees data upfront). isSuccess/isError are derived booleans for convenience.

See

queryOptions to share these options between useQuery and imperative APIs like queryClient.query.

Example

tsx
import { For } from 'solid-js'
import { useQuery } from '@tanstack/solid-query'

function Posts() {
  // `postsQuery.data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the
  // list stays visible alongside the error.
  const postsQuery = useQuery(() => ({
    queryKey: ['posts'],
    queryFn: fetchPosts,
    initialData: [],
  }))

  return (
    <div>
      {postsQuery.isError ? <span>Error: {postsQuery.error.message}</span> : null}
      <ul>
        <For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>
      </ul>
    </div>
  )
}

Parameters

options

DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>

An accessor returning the DefinedInitialDataOptions to use — everything you can pass to useQuery, with initialData set.

options properties

Built from QueryOptions. See the type above for what it changes.

queryClient?

() => QueryClient

An accessor for a custom QueryClient. Otherwise, the one from the nearest context will be used.

Returns

DefinedUseQueryResult<TData, TError>

The current query result, as a Solid store, typed so that status is success — or error if a fetch attempt fails while keeping the existing data (status never resolves to pending in this overload's type, since initialData guarantees data upfront). isSuccess/isError are derived booleans for convenience.

Result properties

PropertyTypeDescription
dataTData | undefinedThe last successfully resolved data for the query.
dataUpdatedAtnumberThe timestamp for when the query most recently returned the status as "success".
errorTError | nullThe error object for the query, if an error was thrown. - Defaults to null.
errorUpdateCountnumberThe sum of all errors.
errorUpdatedAtnumberThe timestamp for when the query most recently returned the status as "error".
failureCountnumberThe failure count for the query. - Incremented every time the query fails. - Reset to 0 when the query succeeds.
failureReasonTError | nullThe failure reason for the query retry. - Reset to null when the query succeeds.
fetchStatus"fetching" | "paused" | "idle"The fetch status of the query. - fetching: Is true whenever the queryFn is executing, which includes initial pending as well as background refetch. - paused: The query wanted to fetch, but has been paused. - idle: The query is not fetching. - See Network Mode for more information.
isEnabledbooleantrue if this observer is enabled, false otherwise.
isErrorbooleanA derived boolean from the status variable, provided for convenience. - true if the query attempt resulted in an error.
isFetchedbooleanWill be true if the query has been fetched.
isFetchedAfterMountbooleanWill be true if the query has been fetched after the component mounted. - This property can be used to not show any previously cached data.
isFetchingbooleanA derived boolean from the fetchStatus variable, provided for convenience. - true whenever the queryFn is executing, which includes initial pending as well as background refetch.
isInitialLoadingbooleanDeprecated isInitialLoading is being deprecated in favor of isLoading and will be removed in the next major version.
isLoadingbooleanIs true whenever the first fetch for a query is in-flight. - Is the same as isFetching && isPending.
isLoadingErrorbooleanWill be true if the query failed while fetching for the first time.
isPausedbooleanA derived boolean from the fetchStatus variable, provided for convenience. - The query wanted to fetch, but has been paused.
isPendingbooleanWill be pending if there's no cached data and no query attempt was finished yet.
isPlaceholderDatabooleanWill be true if the data shown is the placeholder data.
isRefetchErrorbooleanWill be true if the query failed while refetching.
isRefetchingbooleanIs true whenever a background refetch is in-flight, which does not include initial pending. - Is the same as isFetching && !isPending.
isStalebooleanWill be true if the data in the cache is invalidated or if the data is older than the given staleTime.
isSuccessbooleanA derived boolean from the status variable, provided for convenience. - true if the query has received a response with no errors and is ready to display its data.
refetch(options?: RefetchOptions) => Promise<QueryObserverResult<TData, TError>>A function to manually refetch the query.
status"error" | "pending" | "success"The status of the query. - Will be: - pending if there's no cached data and no query attempt was finished yet. - error if the query attempt resulted in an error. - success if the query has received a response with no errors and is ready to display its data.