【问题标题】:Querying nested object from Apollo Client cache fails with "Can't find field [FIELD] on ROOT_QUERY object"从 Apollo 客户端缓存中查询嵌套对象失败,并显示“在 ROOT_QUERY 对象上找不到字段 [FIELD]”
【发布时间】:2020-12-13 11:52:36
【问题描述】:

我的 React 客户端使用查询来检索具有albumId 的相册的所有照片:

const GET_ALBUM_PHOTOS = gql`
  query($albumId: Int!) {
    photos(albumId: $albumId) {
      id
      src
      thumbnail
      ...
    }
  }
`;

当我打开 Apollo Chrome 扩展程序时,我可以看到缓存的记录:

photos({"albumId":"1"}):
0:{"__ref":"PhotoType:6100"}
1:{"__ref":"PhotoType:1284"}
2:{"__ref":"PhotoType:2014"}
3:{"__ref":"PhotoType:2745"}
4:{"__ref":"PhotoType:2425"}
...

现在,当我点击其中一张显示的照片时,在 clickhandler 中我获得了photoId,随后,我想将照片对象上的本地字段isSelected 设置为true

我在resolvers.js内部扩展了客户端的PhotoType:

export const typeDefs = gql`
  extend type Query {
    ...
  }

  extend type Photo {
    isSelected: Boolean!
  }
`;

在显示特定相册照片网格的组件中,我尝试检索由其 id 指定的照片,如下所示:

      const obtainedPhotoId = 1089;

      const photo = client.readQuery({
        query: GET_PHOTO,
        variables: { photoId: obtainedPhotoId },
      });

GET_PHOTO 查询定义为:

const GET_PHOTO = gql`
  query($photoId: Int!) {
    photo(id: $photoId) {
      id
      src
      thumbnail
      ...
    }
  }
`;

(附带说明一下,这两个查询都可以在服务器上完美运行。我还确保不会忘记 variables 对象。)

现在,问题是 Apollo 抛出了 MissingFieldError:"Can't find field 'photo' on ROOT_QUERY object",这是有道理的,因为照片对象位于带有键 photos({"albumId":"1"}) 的列表中。根据我在官方 repo 的问题跟踪器上阅读的文档和各种 cmets,我可能需要定义一个缓存重定向。我试过这个(在很多其他的事情中):

const iMCache = new InMemoryCache({
  addTypename: true,
  cacheRedirects: {
    Query: {
      photo: (_, args, { getCacheKey }) => {
        getCacheKey({ __typename: 'Photo', id: args.id });
      },
    },
  },
});

但是错误仍然没有改变。我还尝试定义一个解析器并将其添加到 Apollo 构造函数中:

  Photo: {
    isSelected: (photo, _, { cache }) => {
      const queryResult = cache.readQuery({
        query: GET_PHOTO,
        variables: { photoId: photo.id },
      });

      if (queryResult) {
        return queryResult.photo;
      }
      return false;
    },
  },

没有变化。

我不确定如何调试它,因为无论我如何更改解析器或重定向,我都会顽固地收到相同的错误消息。我还尝试运行原始查询以按相册检索照片,相册首先将这些对象放入缓存中。令人惊讶的是,它告诉我它找不到查询posts。文档相对模糊,因为没有针对此特定(但据说非常常见)用例的具体示例。我在这里做错了什么?

编辑: 我忘了提到我正在使用 Apollo Client v3。在深入研究之后,我认为CacheRedirects 现在已经过时了,要走的路是typePolicies,但我仍然没有找到实现这项工作的方法。

【问题讨论】:

    标签: reactjs graphql apollo apollo-client graphql-js


    【解决方案1】:

    更多新鲜解决方案:https://www.apollographql.com/docs/react/caching/advanced-topics/#cache-redirects-using-field-policy-read-functions

    错误指向缺少extend type Query { photo(photoId: ID!): Photo - 使用“仅缓存”获取策略...但它是一种不同的字段策略方法。

    【讨论】:

    • 这似乎是前进的方向。但是,对于 fieldPolicies,我遇到的问题是它找不到照片对象的“悬空”引用。我尝试使用 keyFields 功能,以便将对象显示到顶层(在更改的键下),但它没有被拾取。
    • 我尝试使用photo(photoId: Int!): Photo 扩展typeDefs 下的Query,但仍然无法在ROOT_QUERY 对象上找到“照片”字段。
    猜你喜欢
    • 2019-07-29
    • 2018-03-03
    • 2020-03-09
    • 2019-05-28
    • 2021-02-01
    • 2018-12-15
    • 2014-09-02
    • 2018-01-14
    • 2020-06-19
    相关资源
    最近更新 更多