跳至主要内容

API 切片:实用程序

API 切片对象包含各种可用于缓存管理的实用程序,例如实现 乐观更新,以及实现 服务器端渲染

这些包含在 API 对象内的 api.util 中。

信息

此页面上的一些 TS 类型是伪代码,用于说明意图,因为实际的内部类型相当复杂。

updateQueryData

签名

const updateQueryData = (
endpointName: string,
args: any,
updateRecipe: (draft: Draft<CachedState>) => void,
updateProvided?: boolean,
) => ThunkAction<PatchCollection, PartialState, any, AnyAction>

interface PatchCollection {
patches: Patch[]
inversePatches: Patch[]
undo: () => void
}
  • 参数
    • endpointName: 与现有端点名称匹配的字符串
    • args: 与之前查询调用中使用的参数匹配的参数,用于确定需要更新的缓存数据集
    • updateRecipe: 一个 Immer produce 回调函数,可以对缓存状态应用更改
    • updateProvided: 一个布尔值,指示是否应根据更新的缓存重新计算端点的提供标签。默认为 false

描述

一个 Redux thunk 动作创建器,当调度时,它会创建并应用一组 JSON diff/patch 对象到当前状态。这会立即使用这些更改更新 Redux 状态。

thunk 动作创建器接受三个参数:我们要更新的端点的名称(例如 'getPost')、任何相关的查询参数和一个回调函数。回调函数接收当前状态的 Immer 包装的 draft,并且可以修改 draft 以匹配突变成功完成后的预期结果。

thunk 返回一个包含 {patches: Patch[], inversePatches: Patch[], undo: () => void} 的对象。patchesinversePatches 是使用 Immer 的 produceWithPatches 方法 生成的。

这通常用作实现乐观更新的第一步。生成的 inversePatches 可以通过调用 dispatch(patchQueryData(endpointName, args, inversePatches)) 来用于撤消更新。或者,可以直接调用 undo 方法来实现相同的效果。

请注意,前两个参数 (endpointNameargs) 用于确定要更新的现有缓存条目。如果找不到现有缓存条目,则 updateRecipe 回调函数将不会运行。

示例 1

const patchCollection = dispatch(
api.util.updateQueryData('getPosts', undefined, (draftPosts) => {
draftPosts.push({ id: 1, name: 'Teddy' })
}),
)

在上面的示例中,'getPosts' 用于 endpointNameundefined 用于 args。这将匹配查询缓存键 'getPosts(undefined)'

即,它将匹配可能通过以下任何调用创建的缓存条目

api.endpoints.getPosts.useQuery()

useGetPostsQuery()

useGetPostsQuery(undefined, { ...options })

dispatch(api.endpoints.getPosts.initiate())

dispatch(api.endpoints.getPosts.initiate(undefined, { ...options }))

示例 2

const patchCollection = dispatch(
api.util.updateQueryData('getPostById', 1, (draftPost) => {
draftPost.name = 'Lilly'
}),
)

在上面的示例中,'getPostById' 用于 endpointName1 用于 args。这将匹配查询缓存键 'getPostById(1)'

即,它将匹配可能通过以下任何调用创建的缓存条目

api.endpoints.getPostById.useQuery(1)

useGetPostByIdQuery(1)

useGetPostByIdQuery(1, { ...options })

dispatch(api.endpoints.getPostById.initiate(1))

dispatch(api.endpoints.getPostById.initiate(1, { ...options }))

upsertQueryData

签名

const upsertQueryData = <T>(endpointName: string, args: any, newEntryData: T) =>
ThunkAction<Promise<CacheEntry<T>>, PartialState, any, UnknownAction>
  • 参数
    • endpointName: 与现有端点名称匹配的字符串
    • args: 与之前查询调用中使用的参数匹配的参数,用于确定需要更新的缓存数据集
    • newEntryValue: 要写入对应缓存条目data字段的值

描述

一个 Redux thunk 动作创建器,当被分发时,它充当一个模拟的 API 请求,将值插入缓存。

thunk 动作创建器接受三个参数:我们要更新的端点名称(例如 'getPost')、构建所需缓存键的适当查询参数值以及要插入的数据。

如果该缓存键不存在缓存条目,则会创建一个缓存条目并添加数据。如果缓存条目已经存在,这将覆盖现有的缓存条目数据。

thunk 异步执行,并返回一个 promise,该 promise 在存储更新后解析。

如果在实际请求正在进行时分发,则插入和请求将在它们解析后立即处理,从而导致“最后结果获胜”的更新行为。

示例

await dispatch(
api.util.upsertQueryData('getPost', { id: 1 }, { id: 1, text: 'Hello!' }),
)

patchQueryData

签名

const patchQueryData = (
endpointName: string,
args: any
patches: Patch[],
updateProvided?: boolean
) => ThunkAction<void, PartialState, any, UnknownAction>;
  • 参数
    • endpointName: 与现有端点名称匹配的字符串
    • args: 缓存键,用于确定需要更新哪个缓存数据集
    • patches: 要应用于缓存状态的补丁(或逆补丁)数组。这些通常是从分发 updateQueryData 的结果中获得的
    • updateProvided: 一个布尔值,指示是否应根据更新的缓存重新计算端点的提供标签。默认为 false

描述

一个 Redux thunk 动作创建器,当被分发时,它将 JSON diff/patch 数组应用于给定查询结果的缓存数据。这会立即使用这些更改更新 Redux 状态。

thunk 动作创建器接受三个参数:我们要更新的端点名称(例如 'getPost')、构建所需缓存键的适当查询参数值以及 Immer 的 produceWithPatches 生成的 JSON diff/patch 数组。

这通常用作实现乐观更新的第二步。如果请求失败,可以通过分发 patchQueryData 来使用之前由 updateQueryData 生成的 inversePatches 来撤消乐观应用的更改。

在仅希望撤消先前更改的情况下,最好调用从分发 updateQueryData 返回的 undo 方法。

示例

const patchCollection = dispatch(
api.util.updateQueryData('getPosts', undefined, (draftPosts) => {
draftPosts.push({ id: 1, name: 'Teddy' })
}),
)

// later
dispatch(
api.util.patchQueryData(
'getPosts',
undefined,
patchCollection.inversePatches,
),
)

// or
patchCollection.undo()

prefetch

签名

type PrefetchOptions = { ifOlderThan?: false | number } | { force?: boolean }

const prefetch = (endpointName: string, arg: any, options: PrefetchOptions) =>
ThunkAction<void, any, any, UnknownAction>
  • 参数

    • endpointName: 与现有端点名称匹配的字符串
    • args: 缓存键,用于确定需要更新哪个缓存数据集
    • options: 用于确定请求是否应在特定情况下发送的选项
      • ifOlderThan: 如果指定,仅当 new Date() 与上次 fulfilledTimeStamp 之间的差值大于给定值(以秒为单位)时才运行查询
      • force: 如果为 true,则会忽略 ifOlderThan 值(如果已设置),即使查询存在于缓存中,也会运行查询。

描述

一个 Redux thunk action creator,可用于手动触发数据的预取。

thunk action creator 接受三个参数:我们要更新的端点名称(例如 'getPost')、任何相关的查询参数以及一组用于确定是否应根据缓存陈旧程度重新获取数据的选项。

React Hooks 用户很可能永远不需要直接使用它,因为 usePrefetch hook 会在您调用 hook 提供的预取函数时根据需要在内部调度 thunk action creator 结果。

示例

dispatch(api.util.prefetch('getPosts', undefined, { force: true }))

selectInvalidatedBy

签名

function selectInvalidatedBy(
state: RootState,
tags: ReadonlyArray<TagDescription<string>>,
): Array<{
endpointName: string
originalArgs: any
queryCacheKey: QueryCacheKey
}>
  • 参数
    • state: 根状态
    • tags: 一个只读的失效标签数组,其中提供的 TagDescription 是 api 的 tagTypes 属性中提供的字符串之一。例如:
      • [TagType]
      • [{ type: TagType }]
      • [{ type: TagType, id: number | string }]

描述

一个可以选择要失效的查询参数的函数。

该函数接受两个参数:

  • 根状态和
  • 要失效的缓存标签。

它返回一个包含以下内容的数组:

  • 端点名称,
  • 原始参数和
  • queryCacheKey。

示例

const entries = api.util.selectInvalidatedBy(state, ['Post'])
const entries = api.util.selectInvalidatedBy(state, [{ type: 'Post', id: 1 }])
const entries = api.util.selectInvalidatedBy(state, [
{ type: 'Post', id: 1 },
{ type: 'Post', id: 4 },
])

invalidateTags

签名

const invalidateTags = (
tags: Array<TagTypes | FullTagDescription<TagTypes>>,
) => ({
type: string,
payload: tags,
})
  • 参数
    • tags: 要失效的标签数组,其中提供的 TagType 是 api 的 tagTypes 属性中提供的字符串之一。例如:
      • [TagType]
      • [{ type: TagType }]
      • [{ type: TagType, id: number | string }]

描述

一个 Redux action creator,可用于手动使 自动重新获取 的缓存标签失效。

该 action creator 接受一个参数:要使之失效的缓存标签。它返回一个包含这些标签作为有效载荷的动作,以及 API 对应的 invalidateTags 动作类型。

调度此 action creator 的结果将 使 给定标签失效,导致查询在订阅到提供对应标签的缓存数据时自动重新获取。

示例

dispatch(api.util.invalidateTags(['Post']))
dispatch(api.util.invalidateTags([{ type: 'Post', id: 1 }]))
dispatch(
api.util.invalidateTags([
{ type: 'Post', id: 1 },
{ type: 'Post', id: 'LIST' },
]),
)

selectCachedArgsForQuery

签名

function selectCachedArgsForQuery(
state: RootState,
queryName: QueryName,
): Array<QueryArg>
  • 参数
    • state: 根状态
    • queryName:与现有查询端点名称匹配的字符串

描述

一个可以为当前缓存的查询选择参数的函数。

该函数接受两个参数:

  • 根状态和

  • 查询的名称

它返回一个包含每个条目使用的参数的数组。

示例

const args = api.util.selectCachedArgsForQuery(state, 'getPosts')

resetApiState

签名

const resetApiState = () => ({
type: string,
payload: undefined,
})

描述

一个 Redux action creator,可以调度它来手动完全重置 API 状态。这将立即删除所有现有的缓存条目,并且所有查询将被视为“未初始化”。

请注意,钩子 还会在本地组件状态中跟踪状态,并且可能不会被 resetApiState 完全重置。

示例

dispatch(api.util.resetApiState())

getRunningQueriesThunkgetRunningMutationsThunk

签名

getRunningQueriesThunk(): ThunkWithReturnValue<Array<QueryActionCreatorResult<any>>>
getRunningMutationsThunk(): ThunkWithReturnValue<Array<MutationActionCreatorResult<any>>>

描述

如果调度,则返回所有正在运行的查询或变异的 thunk。这些返回值可以像 promise 一样等待。

这对于 SSR 场景非常有用,可以等待以任何方式触发的所有查询(或变异),包括通过钩子调用或手动调度 initiate 动作。

等待所有当前正在运行的查询示例
await Promise.all(dispatch(api.util.getRunningQueriesThunk()))

getRunningQueryThunkgetRunningMutationThunk

签名

getRunningQueryThunk<EndpointName extends QueryKeys<Definitions>>(
endpointName: EndpointName,
args: QueryArgFrom<Definitions[EndpointName]>
): ThunkWithReturnValue<
| QueryActionCreatorResult<
Definitions[EndpointName] & { type: 'query' }
>
| undefined
>

getRunningMutationThunk<EndpointName extends MutationKeys<Definitions>>(
endpointName: EndpointName,
fixedCacheKeyOrRequestId: string
): ThunkWithReturnValue<
| MutationActionCreatorResult<
Definitions[EndpointName] & { type: 'mutation' }
>
| undefined
>

描述

如果调度,则返回给定端点名称 + 参数(或 requestId/fixedCacheKey)组合的单个正在运行的查询(或变异)的 thunk,如果它当前正在运行。如果它当前没有运行,则该函数返回 undefined

这些 thunk 主要用于在未来添加对 suspense 的实验性支持。它们允许编写自定义钩子,这些钩子可以查找 RTK Query 是否已经为某个端点/参数组合运行了查询/突变,并检索它以 throw 作为 promise。