React Apollo 在突变后更新客户端缓存
Posted
技术标签:
【中文标题】React Apollo 在突变后更新客户端缓存【英文标题】:React Apollo updating client cache after mutation 【发布时间】:2020-02-03 21:36:00 【问题描述】:在成功执行突变后,我正在尝试更新我的 chache。这是我的查询和突变:
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"
."
在我的客户端缓存中我可以看到
datadataDojoType ...WITH ALL DATA INSIDE APPART FROM THE NEW DISZIPLINE
和
datadataDisziplineType THE NEW OBJECT
网络上的客户端缓存似乎存在很多混乱。不知何故,提出的解决方案都没有帮助,或者对我没有任何意义。任何帮助将不胜感激。
编辑 1: 也许这有帮助?
ROOT_QUERY: …
"dojo(\"id\":\"1\")": …
generated: false
id: "DojoType:1"
type: "id"
typename: "DojoType"
<prototype>: Object …
<prototype>: Object …
编辑 2
我接受了 Herku 的建议并开始使用 Fragment。但是它似乎仍然不太有效。
我更新的代码:
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)
的结果仍然未定义。有什么建议吗?
【问题讨论】:
【参考方案1】:所以我认为您的实际错误是您必须将 ID 作为字符串提供:variables: id: id.toString()
。你可以看到这两行是不同的:
dojo(\"id\":1)
dojo(\"id\":\"1\")
但我强烈建议使用readFragment
而不是readQuery
并使用提供的ID 更新dojo。这也应该更新查询以及所有查询中出现的所有其他 dojo。您可以在 readFragment
here 上找到文档。
另一个技巧是简单地返回整个 dojo 以响应突变。我会说人们应该少担心这一点,并且不要做太多的缓存更新,因为缓存更新是你的 API 的隐式行为,在你的类型系统中没有。可以在 disziplins
字段中找到新的 disziplin 现在已在您的前端编码。想象一下,您想在此处添加另一个步骤,其中必须先批准新的 disziplins 才能最终进入那里。如果突变返回整个道场,一个简单的后端更改就可以完成这项工作,您的客户不必知道这种行为。
【讨论】:
谢谢。我已经尝试过你所说的,但我仍然无法定义为reault。我已经用新的来源更新了我的问题(编辑 2)。我关注apollographql.com/docs/react/v2.5/advanced/fragments/… 设置片段解析器。 也许你应该在 codesandbox.io 这样的地方发布一个复制版本。现在这是一个非常“调试我的代码”的问题...... 是的,你是对的。但感谢您让我走上正轨。以上是关于React Apollo 在突变后更新客户端缓存的主要内容,如果未能解决你的问题,请参考以下文章
突变后使用订阅和更新创建重复节点 - 使用 Apollo 客户端
如何在 Apollo / GraphQL 发生突变后更新缓存?
突变后 React Apollo 客户端道具 refetchQueries