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
:一個 Immerproduce
回呼,可以對快取狀態套用變更updateProvided
:一個布林值,表示是否應根據更新的快取重新計算端點提供的標籤。預設為false
。
說明
一個 Redux thunk 動作建立器,在派送時,會建立並套用一組 JSON diff/patch 物件到目前的狀態。這會立即使用這些變更更新 Redux 狀態。
thunk 動作建立器接受三個引數:我們要更新的端點名稱(例如 'getPost'
)、任何相關查詢引數,以及一個回呼函式。回呼會收到目前狀態的 Immer 包裝的 draft
,並可以在變更完成後修改 draft 以符合預期的結果。
thunk 會傳回包含 {patches: Patch[], inversePatches: Patch[], undo: () => void}
的物件。patches
和 inversePatches
是使用 Immer 的 produceWithPatches
方法 產生的。
這通常用作實作樂觀更新的第一步。產生的 inversePatches
可用於透過呼叫 dispatch(patchQueryData(endpointName, args, inversePatches))
來回復更新。或者,也可以直接呼叫 undo
方法來達到相同的目的。
請注意,前兩個引數(endpointName
和 args
)用於判斷要更新哪個現有快取項目。如果找不到現有的快取項目,updateRecipe
回呼不會執行。
範例 1
const patchCollection = dispatch(
api.util.updateQueryData('getPosts', undefined, (draftPosts) => {
draftPosts.push({ id: 1, name: 'Teddy' })
}),
)
在上面的範例中,'getPosts'
提供給 endpointName
,undefined
提供給 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'
已提供給 endpointName
,而 1
已提供給 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 會非同步執行,並傳回在更新儲存體時解析的承諾。
如果在實際要求進行中時傳送,上傳和要求將在解析後立即處理,導致「最後結果獲勝」的更新行為。
範例
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 動作建立器,可用於手動觸發資料的預先擷取。
thunk 動作建立器接受三個引數:我們要更新的端點名稱(例如 'getPost'
)、任何相關查詢引數,以及一組選項,用於根據快取過期時間判斷是否實際應重新擷取資料。
React Hooks 使用者很可能永遠不需要直接使用此功能,因為當您呼叫 hook 提供的預先擷取函式時,usePrefetch
hook 會在需要時內部傳送 thunk 動作建立器結果。
範例
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 動作建立器,可用於手動失效快取標籤以進行 自動重新擷取。
動作建立器接受一個參數:要失效的快取標籤。它會傳回一個動作,其中這些標籤作為有效負載,以及對應的 api 的 invalidateTags
動作類型。
發送此動作建立器的結果會 失效 給定的標籤,導致查詢自動重新擷取,如果它們訂閱了提供對應標籤的快取資料 提供。
範例
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 動作建立器,可以發送以手動完全重設 api 狀態。這會立即移除所有現有的快取項目,所有查詢都將被視為「未初始化」。
請注意,掛勾 也會追蹤本地元件狀態中的狀態,且可能無法完全由 resetApiState
重設。
範例
dispatch(api.util.resetApiState())
getRunningQueriesThunk
和 getRunningMutationsThunk
簽章
getRunningQueriesThunk(): ThunkWithReturnValue<Array<QueryActionCreatorResult<any>>>
getRunningMutationsThunk(): ThunkWithReturnValue<Array<MutationActionCreatorResult<any>>>
說明
Thunk(如果已調用)會傳回所有正在執行的查詢或異動。這些傳回值可以像承諾一樣等待。
這對於 SSR 情境很有用,可以等待以任何方式觸發的所有查詢(或異動),包括透過掛鉤呼叫或手動調用initiate
動作。
await Promise.all(dispatch(api.util.getRunningQueriesThunk()))
getRunningQueryThunk
和 getRunningMutationThunk
簽章
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
>
說明
Thunk(如果已調用)會傳回單一正在執行的查詢(或異動),針對給定的端點名稱 + 參數(或 requestId/fixedCacheKey)組合,如果它目前正在執行中。如果它目前沒有執行中,函式會傳回 undefined
。
這些 Thunk 主要新增到未來加入懸念的實驗性支援。它們可以撰寫自訂掛鉤,用於查詢 RTK Query 是否已針對特定端點/參數組合取得正在執行的查詢/異動,並擷取它以 throw
為承諾。