You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RTK Query缓存失效后getUserContacts仍读取旧缓存数据问题

问题:RTK Query删除联系人后getUserContacts仍返回旧缓存数据

删除联系人后,RTK Query触发了getUserContacts和getAllUsersContacts两个查询,但getUserContacts返回的是删除前的旧缓存数据,getAllUsersContacts则能正常从服务器获取最新数据。请求顺序如下:

  1. delete {id} - 200(服务器响应成功)
  2. getUserContacts - 200(返回缓存数据)
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:53:16