此实用工具来自一个单独的包,可通过 '@tanstack/query-persist-client-core' 导入。
npm install @tanstack/query-persist-client-core
npm install @tanstack/query-persist-client-core
或
pnpm add @tanstack/query-persist-client-core
pnpm add @tanstack/query-persist-client-core
或
yarn add @tanstack/query-persist-client-core
yarn add @tanstack/query-persist-client-core
或
bun add @tanstack/query-persist-client-core
bun add @tanstack/query-persist-client-core
注意:此工具也包含在 @tanstack/solid-query-persist-client 包中,因此如果您正在使用该包,则无需单独安装它。
这样,您就不需要存储整个 QueryClient,而是可以选择在应用程序中值得持久化的内容。每个查询都会被惰性恢复(在首次使用该 Query 时)并持久化(在每次运行 queryFn 之后),因此无需进行节流。 staleTime 在恢复 Query 后也会被尊重,因此如果数据被视为 stale,它将在恢复后立即重新获取。如果数据是 fresh,则 queryFn 不会运行。
从内存中垃圾回收 Query 不会影响持久化数据。这意味着 Query 可以保留在内存中更短的时间以提高 内存效率。如果它们在下次使用时,它们将再次从持久化存储中恢复。
import AsyncStorage from '@react-native-async-storage/async-storage'
import { QueryClient } from '@tanstack/solid-query'
import { experimental_createQueryPersister } from '@tanstack/query-persist-client-core'
const persister = experimental_createQueryPersister({
storage: AsyncStorage,
maxAge: 1000 * 60 * 60 * 12, // 12 hours
})
const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 30, // 30 seconds
persister: persister.persisterFn,
},
},
})
import AsyncStorage from '@react-native-async-storage/async-storage'
import { QueryClient } from '@tanstack/solid-query'
import { experimental_createQueryPersister } from '@tanstack/query-persist-client-core'
const persister = experimental_createQueryPersister({
storage: AsyncStorage,
maxAge: 1000 * 60 * 60 * 12, // 12 hours
})
const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 30, // 30 seconds
persister: persister.persisterFn,
},
},
})
createPersister 插件实际上会包装 queryFn,因此如果 queryFn 不运行,它就不会恢复。这样,它就在 Query 和网络之间充当了缓存层。因此,当使用 persister 时, networkMode 默认为 'offlineFirst',以便即使没有网络连接也可以从持久化存储中恢复。
调用 experimental_createQueryPersister 会返回除 persisterFn 之外的其他实用程序,以便更轻松地实现用户区功能。
此函数将 Query 持久化到存储中,并使用创建 persister 时定义的键。
此工具可能与 setQueryData 一起使用,以将乐观更新持久化到存储中,而无需等待失效。
const persister = experimental_createQueryPersister({
storage: AsyncStorage,
maxAge: 1000 * 60 * 60 * 12, // 12 hours
})
const queryClient = useQueryClient()
useMutation({
mutationFn: updateTodo,
onMutate: async (newTodo) => {
...
// Optimistically update to the new value
queryClient.setQueryData(['todos'], (old) => [...old, newTodo])
// And persist it to storage
persister.persistQueryByKey(['todos'], queryClient)
...
},
})
const persister = experimental_createQueryPersister({
storage: AsyncStorage,
maxAge: 1000 * 60 * 60 * 12, // 12 hours
})
const queryClient = useQueryClient()
useMutation({
mutationFn: updateTodo,
onMutate: async (newTodo) => {
...
// Optimistically update to the new value
queryClient.setQueryData(['todos'], (old) => [...old, newTodo])
// And persist it to storage
persister.persistQueryByKey(['todos'], queryClient)
...
},
})
此函数将尝试通过 queryHash 检索已持久化的查询。
如果 query 已 过期、 损坏 或 格式错误,它将被从存储中删除,并返回 undefined。
此函数可用于零星地清理存储中 过期、 损坏 或 格式错误 的条目。
为了使此函数正常工作,您的存储必须公开 entries 方法,该方法将返回一个 键值对数组。
例如, localStorage 的 Object.entries(localStorage) 或 idb-keyval 的 entries。
此函数可用于恢复当前由 persister 存储的查询。
例如,当您的应用程序在离线模式下启动时,或者您希望上一个会话的所有或部分数据在没有中间 loading 状态的情况下立即可用。
filter 对象支持以下属性
为了使此函数正常工作,您的存储必须公开 entries 方法,该方法将返回一个 键值对数组。
例如, localStorage 的 Object.entries(localStorage) 或 idb-keyval 的 entries。
experimental_createQueryPersister(options: StoragePersisterOptions)
experimental_createQueryPersister(options: StoragePersisterOptions)
export interface StoragePersisterOptions {
/** The storage client used for setting and retrieving items from cache.
* For SSR pass in `undefined`.
*/
storage: AsyncStorage | Storage | undefined | null
/**
* How to serialize the data to storage.
* @default `JSON.stringify`
*/
serialize?: (persistedQuery: PersistedQuery) => string
/**
* How to deserialize the data from storage.
* @default `JSON.parse`
*/
deserialize?: (cachedString: string) => PersistedQuery
/**
* A unique string that can be used to forcefully invalidate existing caches,
* if they do not share the same buster string
*/
buster?: string
/**
* The max-allowed age of the cache in milliseconds.
* If a persisted cache is found that is older than this
* time, it will be discarded
* @default 24 hours
*/
maxAge?: number
/**
* Prefix to be used for storage key.
* Storage key is a combination of prefix and query hash in a form of `prefix-queryHash`.
*/
prefix?: string
/**
* Filters to narrow down which Queries should be persisted.
*/
filters?: QueryFilters
}
interface AsyncStorage<TStorageValue = string> {
getItem: (key: string) => MaybePromise<TStorageValue | undefined | null>
setItem: (key: string, value: TStorageValue) => MaybePromise<unknown>
removeItem: (key: string) => MaybePromise<void>
entries?: () => MaybePromise<Array<[key: string, value: TStorageValue]>>
}
export interface StoragePersisterOptions {
/** The storage client used for setting and retrieving items from cache.
* For SSR pass in `undefined`.
*/
storage: AsyncStorage | Storage | undefined | null
/**
* How to serialize the data to storage.
* @default `JSON.stringify`
*/
serialize?: (persistedQuery: PersistedQuery) => string
/**
* How to deserialize the data from storage.
* @default `JSON.parse`
*/
deserialize?: (cachedString: string) => PersistedQuery
/**
* A unique string that can be used to forcefully invalidate existing caches,
* if they do not share the same buster string
*/
buster?: string
/**
* The max-allowed age of the cache in milliseconds.
* If a persisted cache is found that is older than this
* time, it will be discarded
* @default 24 hours
*/
maxAge?: number
/**
* Prefix to be used for storage key.
* Storage key is a combination of prefix and query hash in a form of `prefix-queryHash`.
*/
prefix?: string
/**
* Filters to narrow down which Queries should be persisted.
*/
filters?: QueryFilters
}
interface AsyncStorage<TStorageValue = string> {
getItem: (key: string) => MaybePromise<TStorageValue | undefined | null>
setItem: (key: string, value: TStorageValue) => MaybePromise<unknown>
removeItem: (key: string) => MaybePromise<void>
entries?: () => MaybePromise<Array<[key: string, value: TStorageValue]>>
}
默认选项为
{
prefix = 'tanstack-query',
maxAge = 1000 * 60 * 60 * 24,
serialize = JSON.stringify,
deserialize = JSON.parse,
}
{
prefix = 'tanstack-query',
maxAge = 1000 * 60 * 60 * 24,
serialize = JSON.stringify,
deserialize = JSON.parse,
}