RTK Query的queryFn中能否调用已定义endpoint代替fetchWithBQ
回答
结论:完全可以实现,有两种常用方案适配不同需求
方案1:抽离公共请求逻辑(适合仅复用路径/参数配置)
如果只需要避免重复编写请求路径、参数配置,不需要复用缓存逻辑,可以直接把公共的请求配置抽成独立函数,两个endpoint共同引用即可:
// 抽离公共的device请求配置 const getDeviceQuery = (id: string) => `devices/${id}` export const api = createApi({ reducerPath: "api", baseQuery: fetchBaseQuery({ baseUrl: "url", }), endpoints: (builder) => { return { device: builder.query<Device, string>({ query: getDeviceQuery, }), deployments: builder.query<Deployment[], string>({ queryFn: async (arg, _api, _extraOptions, fetchWithBQ) => { // 直接复用公共配置,无需重复写路径 const result = await fetchWithBQ(getDeviceQuery(arg)); // 后续处理逻辑 return ... }, }), }; }, });
方案2:调用endpoint.initiate()(适合需要完整复用缓存、全量配置逻辑)
如果需要完整复用目标endpoint的缓存、响应转换、错误处理、标签失效等所有逻辑,可以用RTK Query内置的initiate方法,该方法会自动命中已有缓存,没有缓存时才会发起真实请求,完全符合你的需求:
export const api = createApi({ reducerPath: "api", baseQuery: fetchBaseQuery({ baseUrl: "url", }), endpoints: (builder) => { const endpoints = { device: builder.query<Device, string>({ query: (id) => `devices/${id}`, }), deployments: builder.query<Deployment[], string>({ queryFn: async (arg, api, _extraOptions, _fetchWithBQ) => { // 调用已定义的device endpoint,完整走对应逻辑 const deviceResult = await api.dispatch(api.endpoints.device.initiate(arg)) // 错误处理 if (deviceResult.isError) { return { error: deviceResult.error } } // 拿到返回数据(有缓存时直接返回缓存值) const device = deviceResult.data // 后续处理逻辑 return { data: ... } }, }), } return endpoints }, });
注意事项
- 调用
initiate时可通过第二个参数控制订阅行为:传入{ subscribe: false }不会为当前调用创建缓存订阅,数据不会随组件卸载自动清理,适合临时取数场景;默认会创建订阅,缓存保留规则遵循全局/endpoint配置的keepUnusedDataFor参数 - 该方式会完整复用目标endpoint的所有配置,无需重复编写任何逻辑
内容的提问来源于stack exchange,提问作者droyer
相关产品推荐
相关产品推荐

