queryClient.getQueryData
现在只接受 queryKey 作为参数queryClient.getQueryState
现在只接受 queryKey 作为参数refetchInterval
回调函数仅接收 query
作为参数useQuery
中已移除 remove
方法useQuery
中已移除 isDataEqual
选项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 ++]
为了更轻松地迁移 remove 重载,v5 提供了一个 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 再次调用转换函数。
useQuery
中已移除 remove
方法以前,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 issue 以获取更多信息。
useQuery
中已移除 isDataEqual
选项以前,此函数用于指示是使用先前的 data(true)还是新的 data(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 ++]
自定义日志记录器在 4.x 版本中已被弃用,并在本版本中被移除。日志记录仅在开发模式下有效,而在开发模式下,无需传递自定义日志记录器。
我们更新了 browserslist 以生成更现代、更高效、更小的包。您可以在 此处 阅读有关要求的详细信息。
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
选项更具框架无关性,并避免与 hook 的已建立的 React 函数前缀 "use
" 和 "ErrorBoundary" 组件名称混淆,它已重命名为 throwOnError,以更准确地反映其功能。
Error
是错误的默认类型,而不是 unknown虽然在 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 指南。
prefer-query-object-syntax
规则已移除由于现在唯一支持的语法是对象语法,因此不再需要此规则。
我们已移除 keepPreviousData
选项和 isPreviousData
标志,因为它们与 placeholderData
和 isPlaceholderData
标志的功能基本相同。
为了实现与 keepPreviousData
相同的功能,我们已将先前的查询 data 作为参数添加到 placeholderData
中,它接受一个身份函数。因此,您只需要为 placeholderData
提供一个身份函数,或者使用 Tanstack Query 提供的 keepPreviousData
函数。
这里需要注意的是,
useQueries
在placeholderData
函数中不会收到previousData
作为参数。这是由于传递在数组中的查询的动态性质,这可能会导致 placeholder 和 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])
focus
事件现在仅使用 visibilitychange 事件。这是可能的,因为我们只支持支持 visibilitychange 事件的浏览器。这修复了 此处列出的 一系列问题。
navigator.onLine
属性navigator.onLine 在基于 Chromium 的浏览器中效果不佳。存在 大量关于假阴性的问题,这导致查询被错误地标记为 offline。
为了规避这一点,我们现在总是从 online: true 开始,并且只监听 online 和 offline 事件来更新状态。
这应该会降低假阴性的可能性,但是,对于通过 serviceWorkers 加载的离线应用,这可能意味着假阳性,这些应用即使没有互联网连接也能工作。
在 v4 中,我们引入了将自定义 context 传递给所有 react-query hook 的可能性。这允许在 MicroFrontend 中进行适当的隔离。
然而,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 ++]
)
在 v4 中,我们引入了通过 refetchPage 函数定义无限查询要重取的页面的可能性。
然而,重取所有页面可能会导致 UI 不一致。此外,此选项可在例如 queryClient.refetchQueries
上使用,但它只对无限查询有效,而不是“普通”查询。
v5 包含一个用于无限查询的新 maxPages 选项,用于限制存储在查询数据中并随后重取的页面数量。此新功能处理了最初为 refetchPage
页面功能确定的用例,而没有相关的问题。
可以传递给 dehydrate
的选项已简化。Queries 和 Mutations 始终会被脱水(根据默认函数实现)。要更改此行为,而不是使用已移除的布尔选项 dehydrateMutations
和 dehydrateQueries
,您可以实现函数等效的 shouldDehydrateQuery
或 shouldDehydrateMutation
。要获得不进行查询/mutation 脱水的旧行为,请传递 () => false
。
- dehydrateMutations?: boolean // [!code --]
- dehydrateQueries?: boolean // [!code --]
- dehydrateMutations?: boolean // [!code --]
- dehydrateQueries?: boolean // [!code --]
以前,我们将 undefined
传递给 queryFn
作为 pageParam
,并且您可以在 queryFn
函数签名中为 pageParam
参数分配默认值。其缺点是在 queryCache
中存储 undefined
,这是不可序列化的。
相反,现在您必须将显式的 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
现在是无限查询所必需的。
getNextPageParam
或 getPreviousPageParam
返回 null 现在表示没有更多页面可用在 v4 中,您需要明确返回 undefined
来表示没有更多页面可用。我们已扩大此检查范围以包括 null
。
在服务器上,retry
现在默认为 0 而不是 3。对于预取,我们一直默认 0 次重试,但由于具有 suspense
的查询现在也可以在服务器上直接执行(自 React18 起),因此我们必须确保在服务器上根本不重试。
status: loading
已更改为 status: pending
,isLoading
已更改为 isPending
,isInitialLoading
已重命名为 isLoadingloading
状态已重命名为 pending,同样,派生的 isLoading
标志已重命名为 isPending。
对于 Mutations,status
也已从 loading 更改为 pending,isLoading
标志已更改为 isPending。
最后,为查询添加了一个新的派生 isLoading
标志,它实现为 isPending && isFetching。这意味着 isLoading
和 isInitialLoading
具有相同的功能,但 isInitialLoading
已弃用,将在下一个主版本中移除。
要了解此更改背后的原因,请查看 v5 road map 讨论。
hashQueryKey
已重命名为 hashKey因为它可以对 mutation keys 进行哈希处理,并且可以在 useIsMutating
和 useMutationState
的 predicate 函数中使用,这些函数会接收 mutations。
为了修复与 Vue 2 的兼容性,useQueries
composable 现在返回一个包装在 ref 中的 queries 数组。以前返回的是 reactive
,这导致了许多问题
readonly
包装器破坏了 Vue 2 的响应性检测机制。这在 Vue 2.6 中是隐藏的问题,但在 Vue 2.7 中表现为错误。reactive
的根值。通过此更改,所有这些问题都已得到修复。
这也使 useQueries
与其他返回所有值为 refs 的 composables 保持一致。
为了能够跟上 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>
)
}
在这里,我们只是改变了突变运行时 UI 的外观,而不是直接将数据写入缓存。如果您只需要在一个地方显示乐观更新,这将效果最好。有关更多详细信息,请查看 乐观更新文档。
当需要无限滚动或分页时,无限查询非常有用。然而,获取的页面越多,消耗的内存就越多,并且由于所有页面都需要按顺序重取,这也会减慢查询重取过程。
版本 5 为无限查询提供了一个新的 maxPages 选项,允许开发人员限制存储在查询数据中并随后重取的页面数量。您可以根据您想要提供的用户体验和重取性能来调整 maxPages 值。
请注意,无限列表必须是双向的,这需要同时定义 getNextPageParam 和 getPreviousPageParam。
无限查询可以像常规查询一样进行预取。默认情况下,只有查询的第一个页面会被预取,并存储在给定的 QueryKey 下。如果您想预取多个页面,可以使用 pages 选项。有关更多信息,请阅读 预取指南。
useQueries
的新 combine 选项有关更多详细信息,请参阅 useQueries 文档。
有关更多详细信息,请参阅 experimental_createPersister 文档。
以前 vue-query composables 只能在组件的 setup
函数中运行。
我们有一个紧急出口,允许用户在将 queryClient
作为 composable 选项提供的情况下在任何地方运行这些 hook。
现在,您可以在任何支持 injectionContext 的函数中使用 vue-query composables。例如,路由器导航守卫。使用此新功能时,请确保 vue-query composable 在 effectScope
中运行。否则,可能会导致内存泄漏。我们添加了 dev-only
警告来通知用户潜在的误用。