RTK Query缓存失效后getUserContacts仍读取旧缓存数据问题
问题:RTK Query删除联系人后getUserContacts仍返回旧缓存数据
删除联系人后,RTK Query触发了getUserContacts和getAllUsersContacts两个查询,但getUserContacts返回的是删除前的旧缓存数据,getAllUsersContacts则能正常从服务器获取最新数据。请求顺序如下:
delete {id}- 200(服务器响应成功)getUserContacts- 200(返回缓存数据)getAllUsersContacts- 200(返回服务器最新数据)
相关代码
API Service 定义
getAllUsersContacts: builder.query({ query: ({ params}) => ({ url: 'users/contacts', params }), providedTags: (result, error, arg) => result ? [ ...result._embedded.users .map((user) => [...user.contacts.map(({ id }) => ({ type: 'Contact' as const, id }))]) .flat(6), { type: 'Contact', id: 'LIST' } ] : [{ type: 'Contact', id: 'LIST' }] }), getUserContacts: builder.query({ query: ({params}) => ({ url: 'user/contacts', params }), providesTags: (result, error, arg) => result ? [ ...result.contacts.map(({ id }) => ({ type: 'Contact' as const, id })), { type: 'Contact', id: 'LIST' } ] : [{ type: 'Contact' }] }), deleteContact: builder.mutation({ query: ({id}) => ({ url: 'contacts/${id}', method: 'DELETE' }), invalidatesTags: (result, error, arg) => [{ type: 'Contact', id: arg.id }] })
组件调用代码
getUserContacts(根据下拉框选中用户发起请求):
const {data, isFetching} = useGetUserContacts({params: {userName: user?.name}}, {skip: !user})
getAllUsersContacts:
const {data, isFetching} = useGetUsersContacts({params})
解决方案
1. 修正getUserContacts的默认标签
原代码中getUserContacts在请求无结果时返回的标签缺少id: 'LIST',导致和成功分支标签不一致,统一修改为:
getUserContacts: builder.query({ query: ({params}) => ({ url: 'user/contacts', params }), providesTags: (result, error, arg) => result ? [ ...result.contacts.map(({ id }) => ({ type: 'Contact' as const, id })), { type: 'Contact', id: 'LIST' } ] : [{ type: 'Contact', id: 'LIST' }] })
2. 修正deleteContact的URL模板字符串错误
原代码中URL使用单引号无法解析变量id,改为反引号:
deleteContact: builder.mutation({ query: ({id}) => ({ url: `contacts/${id}`, method: 'DELETE' }), invalidatesTags: (result, error, arg) => [{ type: 'Contact', id: arg.id }] })
3. 强制刷新关联查询缓存
在deleteContact的onQueryStarted中手动使Contact LIST标签失效,确保所有关联查询重新请求:
deleteContact: builder.mutation({ query: ({id}) => ({ url: `contacts/${id}`, method: 'DELETE' }), invalidatesTags: (result, error, arg) => [{ type: 'Contact', id: arg.id }], async onQueryStarted({ id }, { dispatch, queryFulfilled }) { try { await queryFulfilled; dispatch( api.util.invalidateTags([{ type: 'Contact', id: 'LIST' }]) ); } catch (err) { // 处理删除请求失败的情况 } } })
原因说明
- 标签不一致:
getUserContacts默认分支缺少LIST标签,导致RTK Query无法识别该查询缓存需要失效,优先返回旧数据。 - URL解析错误:原
deleteContact的URL未正确解析id,可能导致删除操作未实际执行,缓存未被正确标记为失效。 - 手动刷新:通过
onQueryStarted强制使LIST标签失效,确保getUserContacts跳过缓存,从服务器获取最新数据。
内容的提问来源于stack exchange,提问作者rob111
相关产品推荐
相关产品推荐

