自定义查询
RTK Query 对于你的请求如何解析并不关心。你可以使用任何你喜欢的库来处理请求,或者完全不使用库。RTK Query 提供了预期能覆盖大多数用例的合理默认值,同时也允许自定义以改变查询处理以适应特定需求。
使用 baseQuery
自定义查询
处理查询的默认方法是通过 createApi
的 baseQuery
选项,结合端点定义的 query
选项。
为了处理查询,端点被定义为一个 query
选项,它将其返回值传递给用于 API 的通用 baseQuery
函数。
默认情况下,RTK Query 附带了 fetchBaseQuery
,这是一个轻量级的 fetch
包装器,它自动处理请求头和响应解析,类似于常见的库如 axios
。如果 fetchBaseQuery
本身不能满足你 的需求,你可以使用一个包装函数来自定义其行为,或者为 createApi
使用从头开始创建你自己的 baseQuery
函数。
实现一个自定义的 baseQuery
RTK Query 期望 baseQuery
函数被调用时带有三个参数:args
,api
和 extraOptions
。它应该返回一个带有 data
或 error
属性的对象,或者一个解析为返回此类对象的 promise。
基础查询和查询函数必须 始终 自己捕获错误,并在对象中返回它!
function brokenCustomBaseQuery() {
// ❌ 不要让这个自己抛出
const data = await fetchSomeData()
return { data }
}
function correctCustomBaseQuery() {
// ✅ 捕获错误并 _返回_ 它们,以便 RTKQ 逻辑可以跟踪它
try {
const data = await fetchSomeData()
return { data }
} catch (error) {
return { error }
}
}
baseQuery 函数参数
const customBaseQuery = (
args,
{ signal, dispatch, getState },
extraOptions,
) => {
// 省略
}
baseQuery 函数返回值
-
预期的成功结果格式
return { data: YourData }
-
预期的错误结果格式
return { error: YourError }
const customBaseQuery = (
args,
{ signal, dispatch, getState },
extraOptions,
) => {
if (Math.random() > 0.5) return { error: 'Too high!' }
return { data: 'All good!' }
}
这种格式是必需的,以便 RTK Query 可以推断你的响应的返回类型。
在其核心,一个 baseQuery
函数只需要有最小的返回值才能有效;一个带有 data
或 error
属性的对象。由用户决定如何使用提供的参数,以及在函数内部如何处理请求。
fetchBaseQuery 默认值
对于 fetchBaseQuery
特别地,返回类型如下:
Promise<
| {
data: any
error?: undefined
meta?: { request: Request; response: Response }
}
| {
error: {
status: number
data: any
}
data?: undefined
meta?: { request: Request; response: Response }
}
>
-
使用 fetchBaseQuery 的预期成功结果格式
return { data: YourData }
-
使用 fetchBaseQuery 的预期错误结果格式
return { error: { status: number, data: YourErrorData } }
使用 transformResponse
自定义查询响应
createApi
上的单个端点接受一个transformResponse
属性,该属性允许在数据由查询或突变返回并命中缓存之前对其进行操作。
transformResponse
会在成功的 baseQuery
为相应端点返回数据时被调用,transformResponse
的返回值将被用作与该端点调用相关联的缓存数据。
默认情况下,服务器的有效载荷将直接返回。
function defaultTransformResponse(
baseQueryReturnValue: unknown,
meta: unknown,
arg: unknown,
) {
return baseQueryReturnValue
}
要更改它,提供一个如下所示的函数:
transformResponse: (response, meta, arg) =>
response.some.deeply.nested.collection
transformResponse
会在 baseQuery
返回的 meta
属性作为其第二个参数被调用,这可以在确定转换响应时使用。meta
的值取决于使用的 baseQuery
。
transformResponse: (response: { sideA: Tracks; sideB: Tracks }, meta, arg) => {
if (meta?.coinFlip === 'heads') {
return response.sideA
}
return response.sideB
}