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

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

问题描述

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

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

执行此突变时出现错误

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.

也许可以帮上忙吗?

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作为字符串提供:变量:{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.

还有另一种技巧,就是在突变的响应中简单地返回整个dojo.我要说的是,人们应该不那么担心,而不要过多地进行缓存更新,因为缓存更新是您的API的隐式行为,在类型系统中不存在.新的disziplin可以在 disziplins 字段中找到,现在已在您的前端中进行了编码.想象一下,您想在这里添加新的步骤,新的disziplin必须首先获得批准,然后才能在那里发布.如果变异返回整个dojo,则只需进行简单的后端更改即可完成工作,并且您的客户不必知道这种行为.

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天全站免登陆