Redux-Toolkit Query中extra与extraOptions的作用及填充方法
Redux-Toolkit Query(RTKQ)中extra与extraOptions详解及使用示例
1. extra 和 extraOptions 的核心作用
- extra:用于传递给
queryFn或请求拦截逻辑的动态额外数据,比如用户权限标识、请求上下文信息等,主要在自定义查询/请求逻辑中做条件判断使用。 - extraOptions:属于RTKQ请求的配置扩展项,可用来设置请求超时、自定义缓存规则标识等,会被包含在请求元数据中,能在
transformResponse、onQueryStarted等回调中访问,用于调整请求或响应处理逻辑。
2. 在query和queryFn中填充参数的方式
2.1 使用query字段时的传递
当使用RTKQ默认的query对象(非自定义queryFn)时,extra和extraOptions通过调用生成的查询hook的第二个参数传入,在prepareHeaders、transformResponse等回调中可以直接访问到。
2.2 使用queryFn时的传递
自定义queryFn时,这两个参数会作为queryFn的第二个参数(api对象)的属性存在:api.extra和api.extraOptions,同样是从调用hook时的第二个参数传入。
3. 参数传入入口与条件场景构建
不管用query还是queryFn,extra和extraOptions都是在调用RTKQ生成的查询hook时,通过hook的第二个配置参数传入。比如:
const { data } = useGetUserQuery(userId, { extra: { isAdmin: user.isAdmin }, extraOptions: { timeout: 10000 } });
基于这些参数可以构建各种条件场景:
- 用
extra.isAdmin判断是否给请求添加管理员专属请求头; - 用
extraOptions.timeout设置不同请求的超时时间; - 在
transformResponse中根据extraOptions.format决定返回数据的结构。
4. 代码示例
示例1:使用query字段时传递参数
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; const api = createApi({ baseQuery: fetchBaseQuery({ baseUrl: '/api' }), endpoints: (builder) => ({ getUser: builder.query({ query: (userId) => ({ url: `/users/${userId}`, // 在请求头处理中使用extra参数 prepareHeaders: (headers, { extra }) => { if (extra?.isAdmin) { headers.set('X-Admin-Token', 'admin-token-123'); } return headers; } }), // 在响应转换中使用extraOptions参数 transformResponse: (response, meta, { extraOptions }) => { if (extraOptions?.format === 'compact') { return { id: response.id, name: response.name }; } return response; } }) }) }); export const { useGetUserQuery } = api; // 组件中调用 function UserProfile({ userId, user }) { const { data } = useGetUserQuery(userId, { extra: { isAdmin: user.isAdmin }, extraOptions: { format: 'compact' } }); return <div>{data?.name}</div>; }
示例2:使用queryFn自定义逻辑
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; const api = createApi({ baseQuery: fetchBaseQuery({ baseUrl: '/api' }), endpoints: (builder) => ({ getPosts: builder.query({ queryFn: async (pageNum, api, extraOptions, baseQuery) => { // 从api.extra中获取传入的权限标识 const { includeDrafts } = api.extra; // 根据参数构建请求条件 const params = new URLSearchParams(); params.append('page', pageNum); params.append('status', includeDrafts ? 'all' : 'published'); // 调用baseQuery发送请求,使用extraOptions设置超时 const result = await baseQuery({ url: '/posts', params, timeout: extraOptions?.timeout || 5000 }); // 自定义结果处理 if (result.error) { return { error: result.error }; } return { data: result.data }; } }) }) }); export const { useGetPostsQuery } = api; // 组件中调用 function PostList({ page }) { const { user } = useAuth(); const { data } = useGetPostsQuery(page, { extra: { includeDrafts: user.isAdmin }, extraOptions: { timeout: 10000 } }); return ( <ul> {data?.map(post => <li key={post.id}>{post.title}</li>)} </ul> ); }
内容的提问来源于stack exchange,提问作者shawnMarkus
相关产品推荐
相关产品推荐

