【问题标题】:What are the difference in providing the tags for cache invalidation in RTK query?在RTK查询中提供缓存失效标签有什么区别?
【发布时间】:2022-12-15 14:10:31
【问题描述】:

我正在按照官方文档学习 RTK 查询。但是,我不确定像这样进行缓存失效有什么区别

 getUsers: build.query<User[], void>({
      query: () => '/users',
      providesTags: ['User'],
    }),

和这个

 providesTags: (result, error, arg) =>
        result
          ? [...result.map(({ id }) => ({ type: 'Post' as const, id })), 'Post']
          : ['Post'],

文档解释了 For more granular control over the provided data, provided tags can have an associated id. This enables a distinction between 'any of a particular tag type', and 'a specific instance of a particular tag type'. 但是,我不知道这是什么意思。 invalidatesTags 也一样

【问题讨论】:

  • 也许 Redux 教程的 RTK Query Advanced 部分可以更好地解释这一点?它更详细地讨论了这一点。

标签: redux-toolkit rtk-query


【解决方案1】:

在第一种情况下,您提供硬编码标签名称来获取用户。让我们假设您要在用户下显示他们的帖子和“添加帖子”按钮以发送更改以添加帖子。如果我们传递硬编码标签而不是函数,会发生什么

providesTags: ['Post'],

当我们为查询提供标签时,每个查询都会得到一个标签名称有点像 id。所以当我们用ADD POST mutation 向服务器发送 post 请求时,我们将 invalidatesTags:["Post"] 传递给 mutation,所以在 mutation 完成后,mutation 将去查找带有 providesTags: ['Post'] 的查询,它将使用再次提供标签,您的应用商店将填充新数据。这就是使缓存无效的工作原理。

假设您的页面上有 10 个用户,您单击了 User-1 的 Add a Post 按钮。它将运行“ADD POST”突变,然后它会去寻找提供的“POST”标签,并使该查询无效并再次重新获取数据。在您的例子中,为 User-1 运行 mutation,将为所有 10 个用户运行 get 查询。这是一项非常昂贵的工作。您只需使 User-1 的标签无效。

这就是为什么我们传递一个函数以便我们可以动态定义 invalidates 标记名称的原因。它需要 3 个参数,错误很明显

result 是商店里的数据。

arg 是您调用查询时传递的参数。假设您调用了getUserPostQuery(user),您可以使用arg在函数内部访问这个user

providesTags: (result, error, arg) =>
        // i believe it should have been `arg.id`. otherwise id would be undefined. we are fetching user's post
       // result would be the user's posts
        result
          ? [...result.map(({ id }) => ({ type: 'Post' as const, id:arg.id })), 'Post']
          : ['Post'],

所以我们动态定义了我们的标签名称为

  { type: 'Post' as const, id:arg.id }

【讨论】: