在injectEndpoints多切片中使用同名createOne端点遇问题求助
问题描述
我在使用Redux Toolkit Query时,想在两个切片中都用createOne作为端点名称,但遇到了冲突问题:
初始代码
- userSlice.js 文件:
const userSlice = mainApi.injectEndpoints({ endpoints: (builder) => ({ createOne: builder.mutation({ query: () => ({ url: '/users' method: 'POST', credentials: 'include', body: payload, }) }) }) }) export const { useCreateOneMutation } = userSlice
- roomSlice.js 文件:
const roomSlice = mainApi.injectEndpoints({ endpoints: (builder) => ({ createOne: builder.mutation({ query: () => ({ url: '/rooms' method: 'POST', credentials: 'include', body: payload, }) }) }) }) export const { useCreateOneMutation } = roomSlice
遇到的问题与尝试
即便从正确文件导入useCreateOneMutation,调用roomSlice的createOne方法时,系统仍会认为它属于userSlice。我尝试给两个切片添加overrideExisting: true属性:
- userSlice.js 修改后:
const userSlice = mainApi.injectEndpoints({ endpoints: (builder) => ({ // ... }), overrideExisting: true })
- roomSlice.js 修改后:
const roomSlice = mainApi.injectEndpoints({ endpoints: (builder) => ({ // ... }), overrideExisting: true })
但问题仍未解决,且未收到文档中描述的警告(截图:
),请问哪里操作出错了?
解决思路
核心原因:RTK Query端点名称全局唯一
RTK Query的injectEndpoints是往同一个mainApi实例中注入端点,端点名称是全局共享的——不管在哪个文件定义,同名端点都会被覆盖。而overrideExisting: true的作用是允许覆盖已存在的端点,并非让你同时保留两个同名端点,这就是为什么加了该属性后连警告都消失了:你主动允许了覆盖,后注入的端点直接替换了之前的。
正确解决方案
1. 重命名端点(推荐)
给端点添加前缀区分,从根本上避免全局冲突,导出的Hook也会自动对应改名:
- userSlice.js 修改:
const userSlice = mainApi.injectEndpoints({ endpoints: (builder) => ({ createUser: builder.mutation({ // 补上payload参数,原代码遗漏了 query: (payload) => ({ url: '/users', method: 'POST', credentials: 'include', body: payload, }) }) }) }) export const { useCreateUserMutation } = userSlice
- roomSlice.js 修改:
const roomSlice = mainApi.injectEndpoints({ endpoints: (builder) => ({ createRoom: builder.mutation({ query: (payload) => ({ url: '/rooms', method: 'POST', credentials: 'include', body: payload, }) }) }) }) export const { useCreateRoomMutation } = roomSlice
2. 拆分Api实例(特殊场景使用)
如果一定要保留createOne的端点名,可以为每个切片创建独立的Api实例,而非共用mainApi:
- userApi.js:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' const userApi = createApi({ reducerPath: 'userApi', baseQuery: fetchBaseQuery({ baseUrl: '/api' }), endpoints: (builder) => ({ createOne: builder.mutation({ query: (payload) => ({ url: '/users', method: 'POST', credentials: 'include', body: payload, }) }) }) }) export const { useCreateOneMutation } = userApi
- roomApi.js同理创建独立的
roomApi实例,这样两个Api的端点名称各自独立,不会冲突。但这种方式会增加Store复杂度,非必要不推荐。
为什么overrideExisting: true没用?
这个参数的作用是:当你在同一个Api实例中重复注入同名端点时,允许覆盖且不抛出警告。你给两个切片都添加了该属性,后加载的切片会直接覆盖先加载的端点,所以调用时永远只会生效最后注入的那个,不可能同时存在两个createOne端点。
内容的提问来源于stack exchange,提问作者Islam Y-
相关产品推荐
相关产品推荐

