为何Apollo readQuery在目标对象存在时仍执行失败?
嘿,我一眼就看出你在使用Apollo Client的readQuery方法时踩了个缓存匹配的坑!报错提示找不到resolutions({"id":"Resolution:DHSzPa8bvPCDjuAac"})这个字段,但你贴出来的ROOT_QUERY里,resolutions是一个无参数的数组字段,而不是接受id参数的单条查询字段——这就是问题的核心所在!
为什么会报错?
当你调用readQuery时,如果你的查询语句是请求带id参数的resolutions(id: "..."),但缓存里存储的ROOT_QUERY下只有一个直接的resolutions数组(没有带参数的字段条目),Apollo Client就会因为找不到匹配的缓存字段而抛出这个错误。
具体解决办法
根据你的缓存结构,有三种实用的处理方式:
读取数组后手动筛选目标项
既然缓存里存的是数组,最简单的方式就是先把整个数组读出来,再筛选你要的那条数据:const { resolutions } = client.readQuery({ query: gql` query GetAllResolutions { resolutions { id # 这里加上你需要的其他字段,比如name、createdAt等 } } ` }); // 筛选出目标ID对应的条目 const targetResolution = resolutions.find(res => res.id === "Resolution:DHSzPa8bvPCDjuAac");确保缓存中存在带参字段
如果你确实想通过带参数的查询获取单条数据,那得先确认两件事:一是你的GraphQL服务端支持resolutions(id: ID!)(或者单数的resolution(id: ID!))这样的查询;二是你已经执行过这个带参查询(这样缓存里才会生成对应的带参字段)。示例代码如下:// 先执行过带参查询后,再读取缓存 const { resolution } = client.readQuery({ query: gql` query GetSingleResolution($id: ID!) { resolution(id: $id) { id # 其他需要的字段 } } `, variables: { id: "Resolution:DHSzPa8bvPCDjuAac" } });注意:字段名用单数还是复数取决于你的GraphQL Schema定义,要是Schema里复数的
resolutions支持传id参数,直接调整字段名就行。手动写入带参字段到缓存
要是不想重新执行查询,也可以用writeQuery把带参字段手动写入缓存:// 先从数组里拿到目标条目 const { resolutions } = client.readQuery({ query: gql`query GetAllResolutions { resolutions { id } }` }); const targetResolution = resolutions.find(res => res.id === "Resolution:DHSzPa8bvPCDjuAac"); // 写入带参字段到缓存 client.writeQuery({ query: gql` query GetSingleResolution($id: ID!) { resolution(id: $id) { id # 其他字段 } } `, variables: { id: "Resolution:DHSzPa8bvPCDjuAac" }, data: { resolution: targetResolution } }); // 之后就能用readQuery读取这个带参字段了
总结一下
你的缓存里只有无参数的resolutions数组,却尝试读取带参数的resolutions(id: "...")字段,两者不匹配才导致报错。选上面任一方法,要么读数组筛选,要么确保缓存里有带参字段,就能解决问题啦。
内容的提问来源于stack exchange,提问作者VikR

