Skip to content
API Reference

createQuery

ts
const createQuery: {
<TQueryFnData, TError, TData, TQueryKey>  (options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): DefinedUseQueryResult<TData, TError>;
<TQueryFnData, TError, TData, TQueryKey>  (options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): UseQueryResult<TData, TError>;
} = useQuery;

Defined in: packages/solid-query/src/index.ts:57

Call Signature

ts
<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): DefinedUseQueryResult<TData, TError>;

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 known to be defined, so the resulting data is typed as never undefined (unless a select changes TData to include undefined). At runtime, data is still undefined if select throws on its first call.

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 known to be defined.

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 (status never resolves to pending in this overload's type, since initialData guarantees data upfront). status is error if the query has an error from a fetch that failed after its retries or if select threw, and success otherwise. 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>
  )
}

Call Signature

ts
<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): UseQueryResult<TData, TError>;

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 error if the query has an error from a fetch that failed after its retries or if select threw, success if the query has data to display (including placeholderData), and pending otherwise. 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>
  )
}