突变后 React Apollo 更新客户端缓存 [英] React Apollo updating client cache after mutation

查看:34
本文介绍了突变后 React Apollo 更新客户端缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在成功执行突变后更新我的 chache.这是我的查询和突变:

I am trying to update my chache after succesfully executing a mutation. Here is my query and mutation:

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)
        });
      }
    }
    );

当我执行此更改时,我收到错误

when i execute this mutation i get the error

Invariant Violation: "Can't find field dojo({"id":1}) on object {
  "dojo({\"id\":\"1\"})": {
    "type": "id",
    "generated": false,
    "id": "DojoType:1",
    "typename": "DojoType"
  }
}."

在我的客户端缓存中,我可以看到

In my client cache i can see

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

data{data{DisziplineType {THE NEW OBJECT}}

网络上的客户端缓存似乎存在很多混淆.不知何故,提出的解决方案都没有帮助,或者对我来说没有任何意义.任何帮助将不胜感激.

There seems to be a lot of confusion around the client cache around the web. Somehow none of the posed solutions helped, or made any sense to me. Any help would be greatly appreciated.

编辑 1:也许这会有所帮助?

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

编辑 2

我接受了 Herku 的建议并开始使用片段.然而它似乎仍然不太奏效.

I have taken Herku advice and started using fragment. however it still seems to not quite work.

我的旧代码:

 const [createDisziplin] = useMutation(Constants.addDiszipline_MUTATION,
    {
      update(cache, { data: { createDisziplin } }) {
        console.log(cache)
        const { dojo } = cache.readFragment(
          { fragment: Constants.Diszilines_FRAGMENT,
            id:"DojoType:"+id.toString()});
        console.log(dojo)
      }
    }
    );

export const Diszilines_FRAGMENT=gql`
  fragment currentDojo on Dojo{
    id,
    name,
    disziplines{
      id,
      name
    }
  }
`;

然而 console.log(dojo) 的结果仍然未定义.有什么建议吗?

however the result from console.log(dojo) is still undefined.Any advice?

推荐答案

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

So I think your actual error is that you have to supply the ID as as a string: variables: {id: id.toString()}. You can see that these two lines are different:

dojo({\"id\":1})
dojo({\"id\":\"1\"})

但我强烈建议使用 readFragment 而不是 readQuery 并使用提供的 ID 更新 dojo.这也应该更新查询以及所有查询中出现的所有其他 dojo.您可以在 readFragment 此处找到有关文档.

But I would highly suggest to use readFragment instead of readQuery and update the dojo with the ID supplied. This should update the query as well and all other occurrences of the dojo in all your queries. You can find documentation on readFragment here.

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

Another trick is as well to simply return the whole dojo in the response of the mutation. I would say people should be less afraid of that and not do to much cache updates because cache updates are implicit behaviour of your API that is nowhere in your type system. That the new disziplin can be found in the disziplins field is now encoded in your frontend. Imagine you want to add another step here where new disziplins have to be approved first before they end up in there. If the mutation returns the whole dojo a simple backend change would do the job and your clients don't have to be aware of that behaviour.

这篇关于突变后 React Apollo 更新客户端缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆