RTK Query缓存失效中两种标签提供方式的差异解析
一、providesTags 的两种写法差异
1. 全局统一标签写法
getUsers: build.query<User[], void>({ query: () => '/users', providesTags: ['User'], }),
- 这种写法给整个请求的缓存打上全局
User标签,不绑定具体数据的ID。 - 只要有操作触发
invalidatesTags: ['User'],所有关联User标签的缓存(比如该用户列表的缓存)都会直接失效,触发重新请求。
2. 细粒度带ID标签写法
providesTags: (result, error, arg) => result ? [...result.map(({ id }) => ({ type: 'Post' as const, id })), 'Post'] : ['Post'],
- 这种写法会生成两类标签:
- 单条数据专属标签:比如
{ type: 'Post', id: 1 },对应列表中某一篇具体的帖子; - 全局类型标签:
'Post',代表所有Post类型的缓存集合。
- 单条数据专属标签:比如
- 请求成功时,既给每条数据打专属ID标签,也保留全局标签;请求失败时只添加全局标签,避免因结果为空丢失类型标识。
二、官方文档说明的通俗解释
为了对提供的数据进行更精细的控制,提供的标签可以关联一个ID。这样就能区分“某类标签的任意实例”和“某类标签的特定实例”。
简单来说:
- 不带ID的标签(如
['User'])是批量控制开关,触发后会清空该类型下所有缓存; - 带ID的标签(如
{type: 'Post', id: 5})是精准控制开关,只会清空对应ID的单条数据缓存。
三、invalidatesTags 的对应逻辑
- 若使用
invalidatesTags: ['Post']:所有关联Post标签的缓存都会失效,包括帖子列表缓存和所有单篇帖子的缓存,全部触发重新请求; - 若使用
invalidatesTags: [{type: 'Post', id: 5}]:仅ID为5的单篇帖子缓存失效,比如getPost(5)会重新请求,但帖子列表缓存不受影响; - 也可混合使用:
invalidatesTags: [{type: 'Post', id: 5}, 'Post'],既更新单条帖子数据,也强制更新帖子列表缓存。
内容的提问来源于stack exchange,提问作者Nyi Nyi Hmue Aung
相关产品推荐
相关产品推荐

