RTK Query分页场景下如何乐观更新指定endpoint的全部缓存
RTK Query 的缓存是以 endpoint名称 + 接口参数序列化结果 作为唯一key进行存储的,所以原生的updateQueryData确实要求传入对应请求的args参数才能定位到要修改的缓存条目,要更新所有分页的getPosts缓存可以采用以下两种方案:
方案1:批量遍历所有已缓存的分页条目更新
你可以用RTK Query内置的selectCachedArgsForQuery工具方法,拿到当前已经缓存过的所有getPosts请求的参数(也就是所有已经请求过的页码),之后遍历调用updateQueryData即可:
// 从状态中获取所有已经缓存的getPosts接口的参数 const allCachedPageArgs = apiSlice.util.selectCachedArgsForQuery( store.getState(), 'getPosts' ) // 遍历每一页的缓存逐一更新目标帖子数据 allCachedPageArgs.forEach(pageArg => { apiSlice.util.updateQueryData('getPosts', pageArg, draft => { const targetPost = draft.find(post => post.id === postId) if (targetPost) { targetPost.reactions[reaction]++ } }) })
这种方案只会修改已经存在的缓存,不会生成额外的无用缓存,性能开销更低,适合需要纯前端做乐观更新、不需要触发重新请求的场景。
方案2:通过标签失效兜底
如果你的场景允许更新完成后重新拉取最新数据,也可以直接给修改接口配置invalidatesTags,失效所有Post标签对应的缓存,后续用户访问任意分页时都会自动拉取最新数据,无需手动修改缓存:
addReaction: builder.mutation({ query: ({ postId, reaction }) => ({ url: `/posts/${postId}/reactions`, method: 'POST', body: { reaction } }), // 失效所有Post标签的缓存,所有getPosts分页缓存都会被标记为过期 invalidatesTags: ['Post'] })
如果需要同时实现乐观更新和兜底逻辑,可以在mutation的onQueryStarted钩子中先执行方案1的批量缓存更新作为乐观态,请求失败时再调用返回的patchCollection.undo()方法回滚缓存即可,逻辑和单条缓存的乐观更新完全一致。
内容的提问来源于stack exchange,提问作者Grapes
相关产品推荐
相关产品推荐

