queryClient.getQueryData
现在仅接受 queryKey 作为参数queryClient.getQueryState
现在仅接受 queryKey 作为参数refetchInterval
回调函数仅接收 query 参数remove
方法已从 useQuery 中移除isDataEqual
选项已从 useQuery 中移除cacheTime
重命名为 gcTime
useErrorBoundary
选项已重命名为 throwOnError
Error
现在是错误的默认类型,而不是 unknown
prefer-query-object-syntax
规则已移除keepPreviousData
,转而使用 placeholderData
恒等函数focus
事件navigator.onLine
属性context
prop,转而使用自定义 queryClient
实例refetchPage
,转而使用 maxPages
dehydrate
APIinitialPageParam
getNextPageParam
或 getPreviousPageParam
返回 null
现在表示没有更多页面可用status: loading
已更改为 status: pending
,isLoading
已更改为 isPending
,并且 isInitialLoading
现在已重命名为 isLoading
hashQueryKey
已重命名为 hashKey
useQueries
composable 返回 ref
而不是 reactive
useQueries
的新 combine
选项fine grained storage persister
injectionContext
中运行 vue-query
composablesv5 是一个主要版本,因此有一些需要注意的重大更改
useQuery 及其朋友过去在 TypeScript 中有很多重载 - 函数可以被调用的不同方式。这不仅在类型方面难以维护,而且还需要运行时检查来查看第一个和第二个参数的类型,以正确创建选项。
现在我们只支持对象格式。
useQuery(key, fn, options) // [!code --]
useQuery({ queryKey, queryFn, ...options }) // [!code ++]
useInfiniteQuery(key, fn, options) // [!code --]
useInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
useMutation(fn, options) // [!code --]
useMutation({ mutationFn, ...options }) // [!code ++]
useIsFetching(key, filters) // [!code --]
useIsFetching({ queryKey, ...filters }) // [!code ++]
useIsMutating(key, filters) // [!code --]
useIsMutating({ mutationKey, ...filters }) // [!code ++]
useQuery(key, fn, options) // [!code --]
useQuery({ queryKey, queryFn, ...options }) // [!code ++]
useInfiniteQuery(key, fn, options) // [!code --]
useInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
useMutation(fn, options) // [!code --]
useMutation({ mutationFn, ...options }) // [!code ++]
useIsFetching(key, filters) // [!code --]
useIsFetching({ queryKey, ...filters }) // [!code ++]
useIsMutating(key, filters) // [!code --]
useIsMutating({ mutationKey, ...filters }) // [!code ++]
queryClient.isFetching(key, filters) // [!code --]
queryClient.isFetching({ queryKey, ...filters }) // [!code ++]
queryClient.ensureQueryData(key, filters) // [!code --]
queryClient.ensureQueryData({ queryKey, ...filters }) // [!code ++]
queryClient.getQueriesData(key, filters) // [!code --]
queryClient.getQueriesData({ queryKey, ...filters }) // [!code ++]
queryClient.setQueriesData(key, updater, filters, options) // [!code --]
queryClient.setQueriesData({ queryKey, ...filters }, updater, options) // [!code ++]
queryClient.removeQueries(key, filters) // [!code --]
queryClient.removeQueries({ queryKey, ...filters }) // [!code ++]
queryClient.resetQueries(key, filters, options) // [!code --]
queryClient.resetQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.cancelQueries(key, filters, options) // [!code --]
queryClient.cancelQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.invalidateQueries(key, filters, options) // [!code --]
queryClient.invalidateQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.refetchQueries(key, filters, options) // [!code --]
queryClient.refetchQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.fetchQuery(key, fn, options) // [!code --]
queryClient.fetchQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryClient.prefetchQuery(key, fn, options) // [!code --]
queryClient.prefetchQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryClient.fetchInfiniteQuery(key, fn, options) // [!code --]
queryClient.fetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryClient.prefetchInfiniteQuery(key, fn, options) // [!code --]
queryClient.prefetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryClient.isFetching(key, filters) // [!code --]
queryClient.isFetching({ queryKey, ...filters }) // [!code ++]
queryClient.ensureQueryData(key, filters) // [!code --]
queryClient.ensureQueryData({ queryKey, ...filters }) // [!code ++]
queryClient.getQueriesData(key, filters) // [!code --]
queryClient.getQueriesData({ queryKey, ...filters }) // [!code ++]
queryClient.setQueriesData(key, updater, filters, options) // [!code --]
queryClient.setQueriesData({ queryKey, ...filters }, updater, options) // [!code ++]
queryClient.removeQueries(key, filters) // [!code --]
queryClient.removeQueries({ queryKey, ...filters }) // [!code ++]
queryClient.resetQueries(key, filters, options) // [!code --]
queryClient.resetQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.cancelQueries(key, filters, options) // [!code --]
queryClient.cancelQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.invalidateQueries(key, filters, options) // [!code --]
queryClient.invalidateQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.refetchQueries(key, filters, options) // [!code --]
queryClient.refetchQueries({ queryKey, ...filters }, options) // [!code ++]
queryClient.fetchQuery(key, fn, options) // [!code --]
queryClient.fetchQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryClient.prefetchQuery(key, fn, options) // [!code --]
queryClient.prefetchQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryClient.fetchInfiniteQuery(key, fn, options) // [!code --]
queryClient.fetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryClient.prefetchInfiniteQuery(key, fn, options) // [!code --]
queryClient.prefetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++]
queryCache.find(key, filters) // [!code --]
queryCache.find({ queryKey, ...filters }) // [!code ++]
queryCache.findAll(key, filters) // [!code --]
queryCache.findAll({ queryKey, ...filters }) // [!code ++]
queryCache.find(key, filters) // [!code --]
queryCache.find({ queryKey, ...filters }) // [!code ++]
queryCache.findAll(key, filters) // [!code --]
queryCache.findAll({ queryKey, ...filters }) // [!code ++]
queryClient.getQueryData 参数已更改为仅接受 queryKey
queryClient.getQueryData(queryKey, filters) // [!code --]
queryClient.getQueryData(queryKey) // [!code ++]
queryClient.getQueryData(queryKey, filters) // [!code --]
queryClient.getQueryData(queryKey) // [!code ++]
queryClient.getQueryState 参数已更改为仅接受 queryKey
queryClient.getQueryState(queryKey, filters) // [!code --]
queryClient.getQueryState(queryKey) // [!code ++]
queryClient.getQueryState(queryKey, filters) // [!code --]
queryClient.getQueryState(queryKey) // [!code ++]
为了使移除重载的迁移更容易,v5 附带了一个 codemod。
codemod 是尽最大努力帮助你迁移重大更改的尝试。请彻底审查生成的代码!此外,还有一些边缘情况 codemod 无法找到,因此请密切关注日志输出。
如果你想针对 .js 或 .jsx 文件运行它,请使用以下命令
npx jscodeshift@latest ./path/to/src/ \
--extensions=js,jsx \
--transform=./node_modules/@tanstack/react-query/build/codemods/src/v5/remove-overloads/remove-overloads.cjs
npx jscodeshift@latest ./path/to/src/ \
--extensions=js,jsx \
--transform=./node_modules/@tanstack/react-query/build/codemods/src/v5/remove-overloads/remove-overloads.cjs
如果你想针对 .ts 或 .tsx 文件运行它,请使用以下命令
npx jscodeshift@latest ./path/to/src/ \
--extensions=ts,tsx \
--parser=tsx \
--transform=./node_modules/@tanstack/react-query/build/codemods/src/v5/remove-overloads/remove-overloads.cjs
npx jscodeshift@latest ./path/to/src/ \
--extensions=ts,tsx \
--parser=tsx \
--transform=./node_modules/@tanstack/react-query/build/codemods/src/v5/remove-overloads/remove-overloads.cjs
请注意,在 TypeScript 的情况下,你需要使用 tsx 作为解析器;否则,codemod 将无法正确应用!
注意: 应用 codemod 可能会破坏你的代码格式,因此请不要忘记在应用 codemod 后运行 prettier 和/或 eslint!
关于 codemod 如何工作的一些说明
onSuccess、onError 和 onSettled 已从 Queries 中移除。它们尚未触及 Mutations。请参阅 此 RFC,了解此更改背后的动机以及替代方案。
refetchInterval
回调函数仅接收 query 参数这简化了回调的调用方式(refetchOnWindowFocus、refetchOnMount 和 refetchOnReconnect 回调也都只接收 query 参数),并且修复了当回调获取被 select 转换的数据时的一些类型问题。
- refetchInterval: number | false | ((data: TData | undefined, query: Query) => number | false | undefined) // [!code --]
+ refetchInterval: number | false | ((query: Query) => number | false | undefined) // [!code ++]
- refetchInterval: number | false | ((data: TData | undefined, query: Query) => number | false | undefined) // [!code --]
+ refetchInterval: number | false | ((query: Query) => number | false | undefined) // [!code ++]
你仍然可以使用 query.state.data 访问数据,但是,它将不是已被 select 转换的数据。如果你需要访问转换后的数据,你可以对 query.state.data 再次调用转换。
remove
方法已从 useQuery 中移除以前,remove 方法用于从 queryCache 中删除查询,而无需通知观察者。它最适合用于命令式地删除不再需要的数据,例如,当用户注销时。
但是,当查询仍然处于活动状态时执行此操作没有多大意义,因为它只会触发下一个重新渲染的硬加载状态。
如果你仍然需要删除查询,可以使用 queryClient.removeQueries({queryKey: key})
const queryClient = useQueryClient()
const query = useQuery({ queryKey, queryFn })
query.remove() // [!code --]
queryClient.removeQueries({ queryKey }) // [!code ++]
const queryClient = useQueryClient()
const query = useQuery({ queryKey, queryFn })
query.remove() // [!code --]
queryClient.removeQueries({ queryKey }) // [!code ++]
主要是因为围绕类型推断发布了一个重要的修复程序。有关更多信息,请参阅此 TypeScript 问题。
isDataEqual
选项已从 useQuery 中移除以前,此函数用于指示是否使用先前的 data (true) 或新数据 (false) 作为查询的已解析数据。
你可以通过将函数传递给 structuralSharing 来实现相同的功能
import { replaceEqualDeep } from '@tanstack/react-query'
- isDataEqual: (oldData, newData) => customCheck(oldData, newData) // [!code --]
+ structuralSharing: (oldData, newData) => customCheck(oldData, newData) ? oldData : replaceEqualDeep(oldData, newData) // [!code ++]
import { replaceEqualDeep } from '@tanstack/react-query'
- isDataEqual: (oldData, newData) => customCheck(oldData, newData) // [!code --]
+ structuralSharing: (oldData, newData) => customCheck(oldData, newData) ? oldData : replaceEqualDeep(oldData, newData) // [!code ++]
自定义 logger 在版本 4 中已被弃用,并在本版本中已移除。日志记录仅在开发模式下有效,在开发模式下,无需传递自定义 logger。
我们已更新了 browserslist 以生成更现代、性能更高且更小的 bundle。你可以在 此处 阅读有关要求的更多信息。
TanStack Query 一直在类上具有私有字段和方法,但它们并不是真正的私有 - 它们只是在 TypeScript 中是私有的。我们现在使用 ECMAScript 私有类特性,这意味着这些字段现在是真正私有的,并且在运行时无法从外部访问。
几乎每个人都误解了 cacheTime。它听起来像是“数据被缓存的时间量”,但这是不正确的。
cacheTime 只要查询仍在使用, 就不会执行任何操作。它仅在查询不再使用时才开始生效。时间过去后,数据将被“垃圾回收”,以避免缓存增长。
gc 指的是“垃圾回收”时间。它有点技术性,但也是计算机科学中一个相当 广为人知的缩写。
const MINUTE = 1000 * 60;
const queryClient = new QueryClient({
defaultOptions: {
queries: {
- cacheTime: 10 * MINUTE, // [!code --]
+ gcTime: 10 * MINUTE, // [!code ++]
},
},
})
const MINUTE = 1000 * 60;
const queryClient = new QueryClient({
defaultOptions: {
queries: {
- cacheTime: 10 * MINUTE, // [!code --]
+ gcTime: 10 * MINUTE, // [!code ++]
},
},
})
useErrorBoundary
选项已重命名为 throwOnError
为了使 useErrorBoundary 选项更具框架无关性,并避免与已建立的 React 函数前缀“use” (用于 hooks) 和 “ErrorBoundary” 组件名称混淆,它已被重命名为 throwOnError ,以更准确地反映其功能。
即使在 JavaScript 中,你可以 throw 任何东西(这使得 unknown 是最正确的类型),但几乎总是会抛出 Errors (或 Error 的子类)。此更改使得在大多数情况下在 TypeScript 中使用 error 字段更容易。
如果你想抛出非 Error 的东西,你现在必须自己设置泛型
useQuery<number, string>({
queryKey: ['some-query'],
queryFn: async () => {
if (Math.random() > 0.5) {
throw 'some error'
}
return 42
},
})
useQuery<number, string>({
queryKey: ['some-query'],
queryFn: async () => {
if (Math.random() > 0.5) {
throw 'some error'
}
return 42
},
})
有关全局设置不同类型 Error 的方法,请参阅 TypeScript 指南。
由于现在唯一支持的语法是对象语法,因此不再需要此规则
我们已移除 keepPreviousData 选项和 isPreviousData 标志,因为它们的作用与 placeholderData 和 isPlaceholderData 标志大致相同。
为了实现与 keepPreviousData 相同的功能,我们已将之前的查询 data 作为参数添加到 placeholderData 中,它接受一个恒等函数。因此,你只需向 placeholderData 提供一个恒等函数,或使用 Tanstack Query 中包含的 keepPreviousData 函数。
这里需要注意的是,useQueries 在 placeholderData 函数中不会接收 previousData 作为参数。这是因为传递到数组中的查询具有动态性质,这可能会导致占位符和 queryFn 的结果形状不同。
import {
useQuery,
+ keepPreviousData // [!code ++]
} from "@tanstack/react-query";
const {
data,
- isPreviousData, // [!code --]
+ isPlaceholderData, // [!code ++]
} = useQuery({
queryKey,
queryFn,
- keepPreviousData: true, // [!code --]
+ placeholderData: keepPreviousData // [!code ++]
});
import {
useQuery,
+ keepPreviousData // [!code ++]
} from "@tanstack/react-query";
const {
data,
- isPreviousData, // [!code --]
+ isPlaceholderData, // [!code ++]
} = useQuery({
queryKey,
queryFn,
- keepPreviousData: true, // [!code --]
+ placeholderData: keepPreviousData // [!code ++]
});
恒等函数,在 Tanstack Query 的上下文中,指的是始终返回其提供的参数(即数据)不变的函数。
useQuery({
queryKey,
queryFn,
placeholderData: (previousData, previousQuery) => previousData, // identity function with the same behaviour as `keepPreviousData`
})
useQuery({
queryKey,
queryFn,
placeholderData: (previousData, previousQuery) => previousData, // identity function with the same behaviour as `keepPreviousData`
})
但是,此更改有一些注意事项,你必须注意
placeholderData 将始终使你进入 success 状态,而 keepPreviousData 会为你提供先前查询的状态。如果我们在成功获取数据后又收到后台重新获取错误,则该状态可能是 error 。但是,错误本身并未共享,因此我们决定坚持 placeholderData 的行为。
keepPreviousData 为你提供了先前数据的 dataUpdatedAt 时间戳,而使用 placeholderData 时, dataUpdatedAt 将保持在 0 。如果你想在屏幕上持续显示该时间戳,这可能会很烦人。但是,你可以通过 useEffect 来解决。
const [updatedAt, setUpdatedAt] = useState(0)
const { data, dataUpdatedAt } = useQuery({
queryKey: ['projects', page],
queryFn: () => fetchProjects(page),
})
useEffect(() => {
if (dataUpdatedAt > updatedAt) {
setUpdatedAt(dataUpdatedAt)
}
}, [dataUpdatedAt])
const [updatedAt, setUpdatedAt] = useState(0)
const { data, dataUpdatedAt } = useQuery({
queryKey: ['projects', page],
queryFn: () => fetchProjects(page),
})
useEffect(() => {
if (dataUpdatedAt > updatedAt) {
setUpdatedAt(dataUpdatedAt)
}
}, [dataUpdatedAt])
现在专门使用 visibilitychange 事件。这是可能的,因为我们只支持支持 visibilitychange 事件的浏览器。这修复了一系列问题 如此处列出。
navigator.onLine 在基于 Chromium 的浏览器中效果不佳。存在许多关于误报的 问题,这导致 Queries 被错误地标记为 offline 。
为了规避这个问题,我们现在始终以 online: true 开始,并且仅监听 online 和 offline 事件以更新状态。
这应该会降低误报的可能性,但是,对于通过 serviceWorkers 加载的离线应用程序,这可能意味着误报,即使没有互联网连接,这些应用程序也可以工作。
在 v4 中,我们引入了将自定义 context 传递给所有 react-query hooks 的可能性。这允许在使用 MicroFrontends 时进行适当的隔离。
但是, context 是一个仅限 react 的功能。 context 所做的只是让我们访问 queryClient 。我们可以通过允许直接传入自定义 queryClient 来实现相同的隔离。反过来,这将使其他框架能够以框架无关的方式拥有相同的功能。
import { queryClient } from './my-client'
const { data } = useQuery(
{
queryKey: ['users', id],
queryFn: () => fetch(...),
- context: customContext // [!code --]
},
+ queryClient, // [!code ++]
)
import { queryClient } from './my-client'
const { data } = useQuery(
{
queryKey: ['users', id],
queryFn: () => fetch(...),
- context: customContext // [!code --]
},
+ queryClient, // [!code ++]
)
refetchPage
,转而使用 maxPages
在 v4 中,我们引入了使用 refetchPage 函数定义无限查询要重新获取的页面的可能性。
但是,重新获取所有页面可能会导致 UI 不一致。此外,此选项在例如 queryClient.refetchQueries 上可用,但它仅对无限查询有效,而对“普通”查询无效。
v5 包含一个新的 maxPages 选项,用于无限查询,以限制要存储在查询数据中和重新获取的页数。这项新功能处理了最初为 refetchPage 页面功能确定的用例,而没有相关问题。
dehydrate
API你可以传递给 dehydrate 的选项已得到简化。Queries 和 Mutations 始终会被脱水(根据默认函数实现)。要更改此行为,你可以实现函数等效项 shouldDehydrateQuery 或 shouldDehydrateMutation 来代替已移除的布尔选项 dehydrateMutations 和 dehydrateQueries 。要获得完全不水合查询/突变的旧行为,请传入 () => false 。
- dehydrateMutations?: boolean // [!code --]
- dehydrateQueries?: boolean // [!code --]
- dehydrateMutations?: boolean // [!code --]
- dehydrateQueries?: boolean // [!code --]
initialPageParam
之前,我们已将 undefined 传递给 queryFn 作为 pageParam ,你可以在 queryFn 函数签名中为 pageParam 参数分配默认值。这样做有一个缺点,即将 undefined 存储在 queryCache 中,这是不可序列化的。
相反,你现在必须将显式的 initialPageParam 传递给无限查询选项。这将用作第一页的 pageParam
useInfiniteQuery({
queryKey,
- queryFn: ({ pageParam = 0 }) => fetchSomething(pageParam), // [!code --]
+ queryFn: ({ pageParam }) => fetchSomething(pageParam), // [!code ++]
+ initialPageParam: 0, // [!code ++]
getNextPageParam: (lastPage) => lastPage.next,
})
useInfiniteQuery({
queryKey,
- queryFn: ({ pageParam = 0 }) => fetchSomething(pageParam), // [!code --]
+ queryFn: ({ pageParam }) => fetchSomething(pageParam), // [!code ++]
+ initialPageParam: 0, // [!code ++]
getNextPageParam: (lastPage) => lastPage.next,
})
以前,我们允许通过将 pageParam 值直接传递给 fetchNextPage 或 fetchPreviousPage 来覆盖将从 getNextPageParam 或 getPreviousPageParam 返回的 pageParams 。此功能完全不适用于重新获取,并且未被广泛知晓或使用。这也意味着现在无限查询需要 getNextPageParam 。
在 v4 中,你需要显式返回 undefined 以指示没有更多页面可用。我们已扩大此检查范围以包括 null 。
在服务器上, retry 现在默认为 0 而不是 3 。对于预取,我们始终默认为 0 次重试,但是由于启用了 suspense 的查询现在也可以直接在服务器上执行(自 React18 起),因此我们必须确保我们根本不在服务器上重试。
status: loading
已更改为 status: pending
, isLoading
已更改为 isPending
,并且 isInitialLoading
现在已重命名为 isLoading
状态 loading 已被重命名为 pending,类似地,派生的 isLoading 标志已被重命名为 isPending。
对于 mutations 也是如此,status 已从 loading 更改为 pending,并且 isLoading 标志已更改为 isPending。
最后,一个新的派生的 isLoading 标志已添加到查询中,它被实现为 isPending && isFetching。这意味着 isLoading 和 isInitialLoading 具有相同的作用,但 isInitialLoading 现在已被弃用,将在下一个主要版本中删除。
要了解此更改背后的原因,请查看 v5 路线图讨论。
因为它也哈希 mutation 键,并且可以在 useIsMutating 和 useMutationState 的 predicate 函数内部使用,这些函数会传递 mutations。
为了修复与 Vue 2 的兼容性,useQueries 组合式函数现在返回包装在 ref 中的 queries 数组。之前返回的是 reactive,这导致了多个问题
通过此更改,所有这些问题都已修复。
此外,这使 useQueries 与其他将所有值作为 refs 返回的组合式函数对齐。
为了能够提供 Vue 后续版本的新功能,我们现在要求 Vue 3 至少为 v3.3 版本。Vue 2.x 的要求保持不变。
v5 还带来了新功能
我们有一种新的、简化的方法来执行乐观更新,通过利用从 useMutation 返回的 variables
const queryInfo = useTodos()
const addTodoMutation = useMutation({
mutationFn: (newTodo: string) => axios.post('/api/data', { text: newTodo }),
onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})
if (queryInfo.data) {
return (
<ul>
{queryInfo.data.items.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
{addTodoMutation.isPending && (
<li key={String(addTodoMutation.submittedAt)} style={{ opacity: 0.5 }}>
{addTodoMutation.variables}
</li>
)}
</ul>
)
}
const queryInfo = useTodos()
const addTodoMutation = useMutation({
mutationFn: (newTodo: string) => axios.post('/api/data', { text: newTodo }),
onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
})
if (queryInfo.data) {
return (
<ul>
{queryInfo.data.items.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
{addTodoMutation.isPending && (
<li key={String(addTodoMutation.submittedAt)} style={{ opacity: 0.5 }}>
{addTodoMutation.variables}
</li>
)}
</ul>
)
}
在这里,我们仅更改 mutation 运行时 UI 的外观,而不是直接将数据写入缓存。如果我们只需要在一个地方显示乐观更新,这效果最佳。有关更多详情,请查看乐观更新文档。
当需要无限滚动或分页时,无限查询非常有用。但是,您获取的页面越多,消耗的内存就越多,这也会减慢查询重新获取过程,因为所有页面都按顺序重新获取。
版本 5 为无限查询提供了一个新的 maxPages 选项,允许开发人员限制存储在查询数据中并随后重新获取的页面数量。您可以根据您想要提供的 UX 和重新获取性能调整 maxPages 值。
请注意,无限列表必须是双向的,这需要定义 getNextPageParam 和 getPreviousPageParam。
无限查询可以像常规查询一样预取。默认情况下,只会预取查询的第一页,并将存储在给定的 QueryKey 下。如果您想要预取多页,可以使用 pages 选项。阅读预取指南以获取更多信息。
有关更多详情,请参阅 useQueries 文档。
有关更多详情,请参阅 experimental_createPersister 文档。
以前,vue-query 组合式函数只能在组件的 setup 函数中运行。
我们有一个应急方案,如果用户提供 queryClient 作为组合式函数选项,则允许在任何地方运行这些钩子。
现在,您可以在任何支持 injectionContext 的函数中使用 vue-query 组合式函数。例如:路由器导航守卫。当使用此新功能时,请确保 vue-query 组合式函数在 effectScope 中运行。否则可能导致内存泄漏。我们添加了 dev-only 警告,用于告知用户潜在的误用。