跳至主要内容

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 action creator,您可以调度它来触发数据获取查询或变异。

React Hooks 用户最有可能永远不需要直接使用这些,因为 Hooks 会根据需要自动调度这些操作。

在 React Hooks 之外使用操作

在调度操作创建器时,您有责任存储对它返回的 Promise 的引用,以防您想要更新该特定订阅。此外,您必须在组件卸载后手动取消订阅。要了解这需要什么,请参阅 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

描述

一个接受缓存键参数并生成一个新的记忆选择器以使用给定的缓存键读取此端点的缓存数据的函数。生成的 selector 使用 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)),