【发布时间】: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