跳至主要內容

API 切片:端點

API 切片物件內部將有一個 endpoints 欄位。此區段會將您提供給 createApi 的端點名稱對應到用於觸發資料擷取和讀取該端點快取資料的核心 Redux 邏輯(thunk 和選取器)。如果您使用的是 createApi 的 React 專用版本,每個端點定義也會包含該端點自動產生的 React hooks。

每個端點結構包含下列欄位

type EndpointLogic = {
initiate: InitiateRequestThunk
select: CreateCacheSelectorFactory
matchPending: Matcher<PendingAction>
matchFulfilled: Matcher<FulfilledAction>
matchRejected: Matcher<RejectedAction>
}

initiate

簽章

type InitiateRequestThunk = StartQueryActionCreator | StartMutationActionCreator;

type StartQueryActionCreator = (
arg:any,
options?: StartQueryActionCreatorOptions
) => ThunkAction<QueryActionCreatorResult, any, any, UnknownAction>;

type StartMutationActionCreator<D extends MutationDefinition<any, any, any, any>> = (
arg: any
options?: StartMutationActionCreatorOptions
) => ThunkAction<MutationActionCreatorResult<D>, any, any, UnknownAction>;

type SubscriptionOptions = {
/**
* How frequently to automatically re-fetch data (in milliseconds). Defaults to `0` (off).
*/
pollingInterval?: number;
/**
* Defaults to `false`. This setting allows you to control whether RTK Query will try to refetch all subscribed queries after regaining a network connection.
*
* If you specify this option alongside `skip: true`, this **will not be evaluated** until `skip` is false.
*
* Note: requires `setupListeners` to have been called.
*/
refetchOnReconnect?: boolean;
/**
* Defaults to `false`. This setting allows you to control whether RTK Query will try to refetch all subscribed queries after the application window regains focus.
*
* If you specify this option alongside `skip: true`, this **will not be evaluated** until `skip` is false.
*
* Note: requires `setupListeners` to have been called.
*/
refetchOnFocus?: boolean;
};

interface StartQueryActionCreatorOptions {
subscribe?: boolean;
forceRefetch?: boolean | number;
subscriptionOptions?: SubscriptionOptions;
}

interface StartMutationActionCreatorOptions {
/**
* If this mutation should be tracked in the store.
* If you just want to manually trigger this mutation using `dispatch` and don't care about the
* result, state & potential errors being held in store, you can set this to false.
* (defaults to `true`)
*/
track?: boolean;
}

說明

Redux thunk 動作建立器,您可以派送它來觸發資料擷取查詢或突變。

React Hooks 使用者很可能永遠不需要直接使用這些,因為 Hooks 會在需要時自動派送這些動作。

React Hooks 以外的動作使用

在派送動作建立器時,您有責任儲存它傳回的承諾的參考,以防您想要更新該特定訂閱。此外,您必須在元件卸載後手動取消訂閱。若要了解這需要做些什麼,請參閱 Svelte 範例React 類別元件範例

範例

啟動查詢範例
import { useState } from 'react'
import { useAppDispatch } from './store/hooks'
import { api } from './services/api'

function App() {
const dispatch = useAppDispatch()
const [postId, setPostId] = useState<number>(1)

useEffect(() => {
// Add a subscription
const result = dispatch(api.endpoints.getPost.initiate(postId))

// Return the `unsubscribe` callback to be called in the `useEffect` cleanup step
return result.unsubscribe
}, [dispatch, postId])

return (
<div>
<div>Initiate query example</div>
</div>
)
}
啟動突變範例
import { useState } from 'react'
import { useAppDispatch } from './store/hooks'
import { api, Post } from './services/api'

function App() {
const dispatch = useAppDispatch()
const [newPost, setNewPost] = useState<Omit<Post, 'id'>>({ name: 'Ash' })

function handleClick() {
// Trigger a mutation
// The `track` property can be set `false` in situations where we aren't
// interested in the result of the mutation
dispatch(api.endpoints.addPost.initiate(newPost), { track: false })
}

return (
<div>
<div>Initiate mutation example</div>
<button onClick={handleClick}>Add post</button>
</div>
)
}

select

簽章

type CreateCacheSelectorFactory =
| QueryResultSelectorFactory
| MutationResultSelectorFactory

type QueryResultSelectorFactory = (
queryArg: QueryArg | SkipToken,
) => (state: RootState) => QueryResultSelectorResult<Definition>

type MutationResultSelectorFactory<
Definition extends MutationDefinition<any, any, any, any>,
RootState,
> = (
requestId: string | SkipToken,
) => (state: RootState) => MutationSubState<Definition> & RequestStatusFlags

type SkipToken = typeof Symbol

說明

接受快取金鑰引數的函式,並使用指定的快取金鑰產生新的快取選擇器,以使用此端點讀取快取資料。產生的選擇器使用 Reselect 的 createSelector 快取。

在選擇突變結果而不是查詢時,函式接受請求 ID。

RTKQ 在內部定義了一個名為 skipTokenSymbol。如果 skipToken 作為查詢引數傳遞給這些選擇器,則選擇器將傳回預設的未初始化狀態。這可用於避免在給定查詢應被停用時傳回值。

React Hooks 使用者很可能永遠不需要直接使用這些,因為 Hooks 會在需要時自動使用這些選擇器。

注意

每次呼叫 .select(someCacheKey) 都會傳回一個新的選取器函式實例。為了讓記憶化正確運作,您應該為每個快取金鑰建立一個指定的選取器函式,並重複使用該選取器函式實例,而不是每次都建立一個新的選取器實例。

範例

選取查詢範例
import { useState, useMemo } from 'react'
import { useAppDispatch, useAppSelector } from './store/hooks'
import { api } from './services/api'

function App() {
const dispatch = useAppDispatch()
const [postId, setPostId] = useState(1)
// useMemo is used to only call `.select()` when required.
// Each call will create a new selector function instance
const selectPost = useMemo(
() => api.endpoints.getPost.select(postId),
[postId],
)
const { data, isLoading } = useAppSelector(selectPost)

useEffect(() => {
// Add a subscription
const result = dispatch(api.endpoints.getPost.initiate(postId))

// Return the `unsubscribe` callback to be called in the cleanup step
return result.unsubscribe
}, [dispatch, postId])

if (isLoading) return <div>Loading post...</div>

return (
<div>
<div>Initiate query example</div>
<div>Post name: {data.name}</div>
</div>
)
}
選取突變範例
import { useState, useMemo } from 'react'
import { skipToken } from '@reduxjs/toolkit/query'
import { useAppDispatch, useAppSelector } from './store/hooks'
import { api } from './services/api'

function App() {
const dispatch = useAppDispatch()
const [newPost, setNewPost] = useState({ name: 'Ash' })
const [requestId, setRequestId] = useState<typeof skipToken | string>(
skipToken,
)
// useMemo is used to only call `.select(..)` when required.
// Each call will create a new selector function instance
const selectMutationResult = useMemo(
() => api.endpoints.addPost.select(requestId),
[requestId],
)
const { isLoading } = useAppSelector(selectMutationResult)

function handleClick() {
// Trigger a mutation
const result = dispatch(api.endpoints.addPost.initiate(newPost))
// store the requestId to select the mutation result elsewhere
setRequestId(result.requestId)
}

if (isLoading) return <div>Adding post...</div>

return (
<div>
<div>Select mutation example</div>
<button onClick={handleClick}>Add post</button>
</div>
)
}

比對器

一組 Redux Toolkit 動作比對工具程式,用於比對此 thunk 將會派送的 pendingfulfilledrejected 動作。這些工具程式讓您可以在 Redux 動作中比對該端點,例如在 createSlice.extraReducers 或自訂中介軟體中。這些工具程式實作如下

 matchPending: isAllOf(isPending(thunk), matchesEndpoint(endpoint)),
matchFulfilled: isAllOf(isFulfilled(thunk), matchesEndpoint(endpoint)),
matchRejected: isAllOf(isRejected(thunk), matchesEndpoint(endpoint)),