Reactjs 变异后Apollo更新客户端缓存的反应

Reactjs 变异后Apollo更新客户端缓存的反应,reactjs,graphql,apollo,react-apollo,Reactjs,Graphql,Apollo,React Apollo,我正在尝试在成功执行一个变异后更新我的疼痛。以下是我的疑问和建议: export const Dojo_QUERY = gql` query Dojo($id: Int!){ dojo(id: $id){ id, name, logoUrl, location { id, city, country }, members{ id }, disziplines{ id,

我正在尝试在成功执行一个变异后更新我的疼痛。以下是我的疑问和建议:

export const Dojo_QUERY = gql`
query Dojo($id: Int!){
  dojo(id: $id){
    id,
    name,
    logoUrl,
    location {
     id,
     city,
     country
    },
    members{
      id
    },
    disziplines{
      id,
      name
    }
  } 
}`;


export const addDiszipline_MUTATION = gql`
mutation createDisziplin($input:DisziplineInput!,$dojoId:Int!){
  createDisziplin(input:$input,dojoId:$dojoId){
    disziplin{
     name,
     id
    }
  }
}`;
我的电话:

const [createDisziplin] = useMutation(Constants.addDiszipline_MUTATION,
    {
      update(cache, { data: { createDisziplin } }) {
        console.log(cache)
        const { disziplines } = cache.readQuery({ query: Constants.Dojo_QUERY,variables: {id}});
        console.log(disziplines)
        cache.writeQuery({
        ...some update logic (craches in line above)
        });
      }
    }
    );
当我执行这个变异时,我得到了错误

Invariant Violation: "Can't find field dojo({"id":1}) on object {
  "dojo({\"id\":\"1\"})": {
    "type": "id",
    "generated": false,
    "id": "DojoType:1",
    "typename": "DojoType"
  }
}."
在我的客户端缓存中,我可以看到

data{data{DojoType {...WITH ALL DATA INSIDE APPART FROM THE NEW DISZIPLINE}}

web上的客户端缓存似乎有很多混乱之处。不知何故,这些解决方案对我都没有帮助,也没有任何意义。任何帮助都将不胜感激

编辑1: 也许这能帮上忙

ROOT_QUERY: {…}
"dojo({\"id\":\"1\"})": {…}​​​​​
generated: false​​​​​
id: "DojoType:1"​​​​​
type: "id"​​​​​
typename: "DojoType"​​​​​
<prototype>: Object { … }​​​​
<prototype>: Object { … }


但是,
console.log(dojo)
的结果仍然没有定义。有什么建议吗?

所以我认为您的实际错误是必须将ID作为字符串提供:
变量:{ID:ID.toString()}
。您可以看到这两条线是不同的:

dojo({\"id\":1})
dojo({\"id\":\"1\"})
但我强烈建议使用
readFragment
而不是
readQuery
,并使用提供的ID更新dojo。这将更新查询以及所有查询中出现的所有其他dojo。您可以在
readFragment
上找到文档


另一个技巧是简单地返回整个dojo以响应突变。我想说的是,人们应该不那么害怕,也不要做太多的缓存更新,因为缓存更新是API的隐式行为,在类型系统中是不存在的。可以在
disziplins
字段中找到新的disziplin,这一点现在已在前端编码。想象一下,您想在这里添加另一个步骤,即新的分离必须在最终进入之前获得批准。如果变异返回整个dojo,一个简单的后端更改就可以完成这项工作,您的客户端不必知道这种行为。

因此我认为您的实际错误是您必须将ID作为字符串提供:
变量:{ID:ID.toString()}
。您可以看到这两条线是不同的:

dojo({\"id\":1})
dojo({\"id\":\"1\"})
但我强烈建议使用
readFragment
而不是
readQuery
,并使用提供的ID更新dojo。这将更新查询以及所有查询中出现的所有其他dojo。您可以在
readFragment
上找到文档


另一个技巧是简单地返回整个dojo以响应突变。我想说的是,人们应该不那么害怕,也不要做太多的缓存更新,因为缓存更新是API的隐式行为,在类型系统中是不存在的。可以在
disziplins
字段中找到新的disziplin,这一点现在已在前端编码。想象一下,您想在这里添加另一个步骤,即新的分离必须在最终进入之前获得批准。如果变异返回整个dojo,一个简单的后端更改就可以了,您的客户不必知道这种行为。

谢谢。我已经试过你说的话了,但结果还是不清楚。我已经用新的来源更新了我的问题(编辑2)。接下来我介绍了片段解析器的设置。也许你应该在类似的地方发布一个复制版本。这是一个“调试我的代码”的问题…是的,你说得对。但是谢谢你让我走上正轨。谢谢。我已经试过你说的话了,但结果还是不清楚。我已经用新的来源更新了我的问题(编辑2)。接下来我介绍了片段解析器的设置。也许你应该在类似的地方发布一个复制版本。这是一个非常“调试我的代码”的问题…是的,你是对的。但是谢谢你让我走上正确的轨道。
export const Diszilines_FRAGMENT=gql`
  fragment currentDojo on Dojo{
    id,
    name,
    disziplines{
      id,
      name
    }
  }
`;
dojo({\"id\":1})
dojo({\"id\":\"1\"})