【问题标题】:How to use RTK Query's 'upsertQueryData' to add a new entry to the cache?如何使用 RTK 查询的 \'upsertQueryData\' 将新条目添加到缓存中?
【发布时间】:2023-01-27 01:25:18
【问题描述】:

我有一个使用 Redux 工具包的“RTK 查询”数据获取功能的 GraphQL 查询设置。在与此查询相关的突变之后,我想将突变返回的数据添加到缓存中,而无需再次向服务器调用查询。为此,我使用了 API 切片实用程序中的 thunk 动作创建器 upsertQueryData。 (Reference Documentation)。

到目前为止,我只能覆盖与查询相关的完整缓存集合集合,但没有找到只添加 1 个条目的方法。也许有人知道我做错了什么?

GraphQL 查询,工作正常。它返回“站点”的集合。

    endpoints: (builder) => ({
      getSites: builder.query({
        query: () => ({
          document: gql`
            query MyQuery {
              sites {
                id
                name
                description
              }
            }
          `,
        }),
      }),
      ...

使用upsertQueryData 的突变。这将覆盖缓存的整个“站点”集合,而不是使用添加 1 个站点。要清楚:发送突变时,我还没有 id,这是服务器通过突变回调返回的。

    createSite: builder.mutation({
        query: ({name}) => ({
          document: gql`
          mutation createSite {
            createSite(
              name: "${name}"
              description: "The workspace where Peter works from home in Dordrecht",
              ) {
              site {
                id
                name
                description
              }
            }
          }
        `
        }),
        async onQueryStarted({}, { dispatch, queryFulfilled }) {
          const { data } = await queryFulfilled;
          const newSiteEntry = data.createSite.site;
          sites.util.upsertQueryData('getSites', { newSiteEntry.id }, newSiteEntry);
        }

我希望它将 1 个日期对象添加到站点缓存对象而不是覆盖它。所以你会在缓存中得到这样的东西:

sites: [ 
    {id: '1', name: 'Existing site 1', description: 'description 1'},
    {id: '2', name: 'Existing site 2', description: 'description 2'},
    {id: '3', name: 'New site', description: 'new description'},
]

【问题讨论】:

    标签: reactjs redux graphql redux-toolkit rtk-query


    【解决方案1】:

    您通常对这里的缓存有错误的概念。由于您的 getSites 端点不带任何参数,并且您可能只调用过 useGetSitesQuery(),因此只有一个缓存条目(称为 getSites(undefined)),并且您想用其他行更新该现有缓存条目。

    upsertQueryData 用于用新值覆盖整个缓存条目,或者在您的情况下,创建您永远不会读取的完全不相关的缓存条目 - 不是您想做的。

    因此,您想要 updateQueryData 代替那个现有的缓存条目:

    dispatch(
      api.util.updateQueryData('getSites', undefined, (draft) => {
        draft.sites.push(newSiteEntry)
      })
    )
    

    请记住,尽管我们通常建议使用 providesTags/invalidatesTags 来自动重新获取其他端点,而不是手动对它们进行乐观更新。

    【讨论】:

      最近更新 更多