useQuery
概述
1function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): DefinedUseQueryResult<TData, TError>;2function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): UseQueryResult<TData, TError>;DefinedInitialDataOptions→DefinedUseQueryResult:订阅一个查询:一种声明式依赖,依赖于与唯一查询键关联的异步数据源。查询会在选项要求时执行 —enabled: false会跳过初始拉取。UndefinedInitialDataOptions→UseQueryResult:订阅一个查询:一种声明式依赖,依赖于与唯一查询键关联的异步数据源。查询会在选项要求时执行 —enabled: false会跳过初始拉取。
调用签名
1function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): DefinedUseQueryResult<TData, TError>;定义于:packages/solid-query/src/useQuery.ts:57
订阅一个查询:一种声明式依赖,依赖于与唯一查询键关联的异步数据源。
查询会在选项要求时执行 — enabled: false 会跳过初始拉取。
当 initialData 已知为已定义时,将选择此重载,因此所得 data 永远不会是 undefined(除非 select 将 TData 更改为包含 undefined)。
类型参数
TQueryFnData
TQueryFnData = unknown
TError
TError = Error
TData
TData = TQueryFnData
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
参数
options
DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>
一个返回 DefinedInitialDataOptions 的访问器 — 即可传入 useQuery 的全部选项,且 initialData 已知为已定义。
queryClient?
() => QueryClient
一个返回自定义 QueryClient 的访问器。否则,将使用最近上下文中的 QueryClient。
返回值
DefinedUseQueryResult<TData, TError>
当前查询结果,以 Solid store 形式返回,其类型确保 status 为 success — 若拉取尝试失败但保留了现有数据,则为 error(在此重载的类型中,status 永远不会解析为 pending,因为 initialData 保证了数据的前置提供)。isSuccess/isError 是为方便起见派生的布尔值。
参阅
使用 queryOptions 在 useQuery 和 queryClient.query 等命令式 API 之间共享这些选项。
示例
1import { For } from 'solid-js'2import { useQuery } from '@tanstack/solid-query'3 4function Posts() {5 // `postsQuery.data` is never `undefined`, thanks to `initialData` — even if a refetch fails, so the6 // list stays visible alongside the error.7 const postsQuery = useQuery(() => ({8 queryKey: ['posts'],9 queryFn: fetchPosts,10 initialData: [],11 }))12 13 return (14 <div>15 {postsQuery.isError ? <span>Error: {postsQuery.error.message}</span> : null}16 <ul>17 <For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>18 </ul>19 </div>20 )21}调用签名
1function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends readonly unknown[] = readonly unknown[]>(options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>, queryClient?: () => QueryClient): UseQueryResult<TData, TError>;定义于:packages/solid-query/src/useQuery.ts:228
订阅一个查询:一种声明式依赖,依赖于与唯一查询键关联的异步数据源。
查询会在选项要求时执行 — enabled: false 会跳过初始拉取。
类型参数
TQueryFnData
TQueryFnData = unknown
TError
TError = Error
TData
TData = TQueryFnData
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
参数
options
UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>
一个返回 UndefinedInitialDataOptions 的访问器 — 即可传入 useQuery 的全部选项。
queryClient?
() => QueryClient
一个返回自定义 QueryClient 的访问器。否则,将使用最近上下文中的 QueryClient。
返回值
UseQueryResult<TData, TError>
当前查询结果,以 Solid store 形式返回。若无缓存数据可供显示,则 status 为 pending;若上次拉取尝试失败,则为 error;若查询已有数据可供显示,则为 success。isPending/isSuccess/isError 是为方便起见派生的布尔值。
参阅
使用 queryOptions 在 useQuery 和 queryClient.query 等命令式 API 之间共享这些选项。
示例
1import { For, Match, Switch } from 'solid-js'2import { useQuery } from '@tanstack/solid-query'3 4function Posts() {5 const postsQuery = useQuery(() => ({6 queryKey: ['posts'],7 queryFn: fetchPosts,8 }))9 10 return (11 <Switch>12 <Match when={postsQuery.isPending}>Loading...</Match>13 <Match when={postsQuery.isError}>Error: {postsQuery.error.message}</Match>14 <Match when={postsQuery.isSuccess}>15 <ul>16 <For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>17 </ul>18 <div>{postsQuery.isFetching ? 'Background Updating...' : ' '}</div>19 </Match>20 </Switch>21 )22}select 从缓存值中派生组件所需的 data,而不改变缓存中实际存储的内容 — 缓存仍保存完整的 Post[],但此处的 data 是一个 number:
1import { Match, Switch } from 'solid-js'2import { useQuery } from '@tanstack/solid-query'3 4function PostCount() {5 const postsQuery = useQuery(() => ({6 queryKey: ['posts'],7 queryFn: fetchPosts,8 select: (posts) => posts.length,9 }))10 11 return (12 <Switch>13 <Match when={postsQuery.isPending}>Loading...</Match>14 <Match when={postsQuery.isError}>Error: {postsQuery.error.message}</Match>15 <Match when={postsQuery.isSuccess}>{postsQuery.data} posts</Match>16 </Switch>17 )18}一个依赖型查询,仅在 postId 设置后启用:
1import { Match, Switch } from 'solid-js'2import { useQuery } from '@tanstack/solid-query'3 4function Post(props: { postId: number | undefined }) {5 const postQuery = useQuery(() => ({6 queryKey: ['post', props.postId],7 queryFn: () => fetchPost(props.postId!),8 enabled: props.postId != null,9 }))10 11 return (12 <Switch fallback={<h1>{postQuery.data?.title}</h1>}>13 <Match when={props.postId == null}>Select a post</Match>14 <Match when={postQuery.isLoading}>Loading...</Match>15 <Match when={postQuery.isError}>Error: {postQuery.error.message}</Match>16 </Switch>17 )18}相同的依赖型查询,使用 skipToken 以类型安全方式禁用,而非依赖 enabled。仍需非空断言 — Solid 的 props 类型收窄无法在 queryFn 闭包中延续(不像局部 const 那样),但 skipToken 可在不使用该断言的情况下保持 queryFn 返回类型的准确性。当 queryFn 为 skipToken 时,refetch 不起作用 — 如需手动触发查询,请改用 enabled: false:
1import { Match, Switch } from 'solid-js'2import { skipToken, useQuery } from '@tanstack/solid-query'3 4function Post(props: { postId: number | undefined }) {5 const postQuery = useQuery(() => ({6 queryKey: ['post', props.postId],7 queryFn: props.postId != null ? () => fetchPost(props.postId!) : skipToken,8 }))9 10 return (11 <Switch fallback={<h1>{postQuery.data?.title}</h1>}>12 <Match when={props.postId == null}>Select a post</Match>13 <Match when={postQuery.isLoading}>Loading...</Match>14 <Match when={postQuery.isError}>Error: {postQuery.error.message}</Match>15 </Switch>16 )17}从已缓存的列表中预填充详情查询,以跳过加载状态。initialDataUpdatedAt 继承列表自身的拉取时间,因此若设置了 staleTime,则其计时起点为列表拉取时刻,而非当前时刻:
1import { useQuery, useQueryClient } from '@tanstack/solid-query'2 3function Post(props: { postId: number }) {4 const queryClient = useQueryClient()5 6 const postQuery = useQuery(() => ({7 queryKey: ['post', props.postId],8 queryFn: () => fetchPost(props.postId),9 initialData: () =>10 queryClient11 .getQueryData<Array<Post>>(['posts'])12 ?.find((post) => post.id === props.postId),13 initialDataUpdatedAt: () =>14 queryClient.getQueryState(['posts'])?.dataUpdatedAt,15 }))16 17 return postQuery.isError ? <span>Error: {postQuery.error.message}</span> : <h1>{postQuery.data?.title}</h1>18}分页数据,在下一页加载期间保持上一页数据可见:
1import { For, createSignal } from 'solid-js'2import { keepPreviousData, useQuery } from '@tanstack/solid-query'3 4function Posts() {5 const [page, setPage] = createSignal(0)6 7 const postsQuery = useQuery(() => ({8 queryKey: ['posts', page()],9 queryFn: () => fetchPosts(page()),10 placeholderData: keepPreviousData,11 }))12 13 return (14 <div>15 <ul>16 <For each={postsQuery.data}>{(post) => <li>{post.title}</li>}</For>17 </ul>18 <button19 disabled={postsQuery.isPlaceholderData}20 onClick={() => setPage((old) => old + 1)}21 >22 Next Page23 </button>24 </div>25 )26}参数
options
UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>
一个返回 UndefinedInitialDataOptions 的访问器 — 即可传入 useQuery 的全部选项。
options 属性
基于 QueryOptions 构建。参见上方类型说明其变更内容。
queryClient?
() => QueryClient
一个返回自定义 QueryClient 的访问器。否则,将使用最近上下文中的 QueryClient。
返回值
UseQueryResult<TData, TError>
当前查询结果,以 Solid store 形式返回。若无缓存数据可供显示,则 status 为 pending;若上次拉取尝试失败,则为 error;若查询已有数据可供显示,则为 success。isPending/isSuccess/isError 是为方便起见派生的布尔值。
返回值属性
| 属性 | 类型 | 描述 |
|---|---|---|
data |
TData | undefined |
查询最后一次成功解析的数据。 |
dataUpdatedAt |
number |
查询最近一次将 status 返回为 "success" 的时间戳。 |
error |
TError | null |
查询的错误对象(若抛出错误)。 - 默认为 null。 |
errorUpdateCount |
number |
所有错误的总和。 |
errorUpdatedAt |
number |
查询最近一次将 status 返回为 "error" 的时间戳。 |
failureCount |
number |
查询的失败次数。 - 每次查询失败时递增。 - 查询成功时重置为 0。 |
failureReason |
TError | null |
查询重试的失败原因。 - 查询成功时重置为 null。 |
fetchStatus |
"fetching" | "paused" | "idle" |
查询的拉取状态。 - fetching:当 queryFn 正在执行时为 true,包括初始 pending 及后台重新拉取。 - paused:查询本应拉取,但已被 paused。 - idle:查询未在拉取。 - 更多信息请参阅 网络模式。 |
isEnabled |
boolean |
若此观察者已启用则为 true,否则为 false。 |
isError |
boolean |
基于 status 变量派生的布尔值,为方便起见提供。 - 若查询尝试导致错误则为 true。 |
isFetched |
boolean |
若查询已完成拉取则为 true。 |
isFetchedAfterMount |
boolean |
若查询在组件挂载后完成拉取则为 true。 - 此属性可用于避免显示任何先前缓存的数据。 |
isFetching |
boolean |
基于 fetchStatus 变量派生的布尔值,为方便起见提供。 - 当 queryFn 正在执行时为 true,包括初始 pending 及后台重新拉取。 |
isInitialLoading |
boolean |
已弃用 isInitialLoading 已被 isLoading 取代,将在下一个主版本中移除。 |
isLoading |
boolean |
查询首次拉取正在进行中时为 true。 - 与 isFetching && isPending 相同。 |
isLoadingError |
boolean |
若查询首次拉取失败则为 true。 |
isPaused |
boolean |
基于 fetchStatus 变量派生的布尔值,为方便起见提供。 - 查询本应拉取,但已被 paused。 |
isPending |
boolean |
若无缓存数据且尚无查询尝试完成则为 pending。 |
isPlaceholderData |
boolean |
若所显示数据为占位数据则为 true。 |
isRefetchError |
boolean |
若查询在重新拉取时失败则为 true。 |
isRefetching |
boolean |
后台重新拉取正在进行中时为 true,不包括 初始 pending。 - 与 isFetching && !isPending 相同。 |
isStale |
boolean |
若缓存中的数据已失效,或数据早于给定 staleTime 则为 true。 |
isSuccess |
boolean |
基于 status 变量派生的布尔值,为方便起见提供。 - 若查询已收到无错误响应且准备就绪以显示其数据则为 true。 |
refetch |
(options?: RefetchOptions) => Promise<QueryObserverResult<TData, TError>> |
用于手动重新拉取查询的函数。 |
status |
"error" | "pending" | "success" |
查询的状态。 - 可能为: - pending:若无缓存数据且尚无查询尝试完成。 - error:若查询尝试导致错误。 - success:若查询已收到无错误响应且准备就绪以显示其数据。 |