Suspense
useQuery
ParametersAccessor<QueryOptions>
queryKey: unknown[]
queryFn: (context: QueryFunctionContext) => Promise<TData>
enabled: boolean
select: (data: TData) => unknown
placeholderData: TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TData
deferStream: boolean
reconcile: false | string | ((oldData: TData | undefined, newData: TData) => TData)
gcTime: number | Infinity
networkMode: 'online' | 'always' | 'offlineFirst
initialData: TData | () => TData
initialDataUpdatedAt: number | (() => number | undefined)
meta: Record<string, unknown>
queryKeyHashFn: (queryKey: QueryKey) => string
refetchInterval: number | false | ((query: Query) => number | false | undefined)
refetchIntervalInBackground: boolean
refetchOnMount: 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) => boolean
retryOnMount: boolean
retryDelay: number | (retryAttempt: number, error: TError) => number
staleTime: number | Infinity
throwOnError: undefined | boolean | (error: TError, query: Query) => boolean
Accessor<QueryClient>
useQuery
Return Value - Store<QueryResult<TData, TError>>
status: QueryStatus
isPending: boolean
isSuccess: boolean
isError: boolean
isLoadingError: boolean
isRefetchError: boolean
data: Resource<TData>
dataUpdatedAt: number
error: null | TError
errorUpdatedAt: number
isStale: boolean
isPlaceholderData: boolean
isFetched: boolean
isFetchedAfterMount: boolean
fetchStatus: FetchStatus
isFetching: boolean
isPaused: boolean
isRefetching: boolean
isLoading: boolean
isInitialLoading: boolean
failureCount: number
failureReason: null | TError
errorUpdateCount: number
refetch: (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: