我正在关注有关GraphQL的教程,在视频中,作者没有使用refetchQueries进行deleteMutation,并且都可以很好地与UI更新和变异一起使用。但是在这里,项目沙箱中的代码已更新,现在refetchQuery用于Job组件->第20行-> deleteJob():codeSandBox上的此操作。
我的应用程序中存在类似的问题,如果没有在任何地方进行refetchQueries都不会自动更新UI。如果我理解正确的话,Apollo不应通过apollo-cache-memory自动应用Apollo的缓存,执行突变并以这种突变方式更新UI。
带有阿波罗升压功能的开箱即用示例:
export default gql`
mutation deleteItem($id: uuid!) {
delete_item(where: {id:{_eq: $id }}){
returning {
id
}
}
}`;
const onDeleteItem = (id) => {
deleteItem({
variables: { id },
});
};
对此有任何建议或经验吗?
答案 0 :(得分:2)
答案是相对简单的:GraphQL中没有通用的方法来告知客户端实体已被删除。让我们首先将其与更新突变进行比较。想象一下,我们正在更新缓存中已有的作业之一。首先是缓存(简化后,实际上与Apollo内部的外观并不完全一样):
$ es61 /orthography
Current working directory: /Users/jonathanleffler/soq
Executing 'ls -a -l' in /orthography
es61: /orthography is not a valid directory
Process 64463 exited with normal status 0x0100 (status 1 = 0x01)
$ es61 $PWD
Current working directory: /Users/jonathanleffler/soq
Executing 'ls -a -l' in /Users/jonathanleffler/soq
total 1016
drwxr-xr-x 100 jonathanleffler staff 3200 Oct 31 15:53 .
drwxr-xr-x+ 69 jonathanleffler staff 2208 Oct 31 15:53 ..
…
-rwxr-xr-x 1 jonathanleffler staff 9028 Oct 31 15:53 es61
-rw-r--r-- 1 jonathanleffler staff 1806 Oct 31 15:53 es61.c
drwxr-xr-x 3 jonathanleffler staff 96 Oct 31 15:43 es61.dSYM
drwxr-xr-x 9 jonathanleffler staff 288 Nov 5 2018 etc
…
-rw-r--r-- 1 jonathanleffler staff 390 Nov 16 2017 makefile
…
Process 64557 exited with normal status 0x0000 (status 0 = 0x00)
$
如果Apollo现在从更新突变中获得了答案,则如下所示:
{
"Query": {
"jobs": ["Job:1", "Job:2"],
},
"Job:1": {
"__typename": "Job",
"id": 1,
"company": "Big Corp",
"title": "Sales Specialist"
},
"Job:2": {
"__typename": "Job",
"id": 2,
"company": "Big Corp",
"title": "GraphQL Expert"
}
}
它可以使用{
"data": {
"updateJob": {
"__typename": "Job",
"id": 2,
"company": "Big Corp",
"title": "GraphQL Unicorn"
}
}
}
函数来了解该对象属于我们规范化缓存中的缓存键dataIdFromObject
。 Apollo可以假定此版本比旧版本新,并以优先于较新结果的方式合并密钥。现在,我们的缓存如下所示:
"Job:2"
然后{
"Query": {
"jobs": ["Job:1", "Job:2"],
},
"Job:1": { ... },
"Job:2": {
"__typename": "Job",
"id": 2,
"company": "Big Corp",
"title": "GraphQL Unicorn" // updated!
}
}
查询将自动使用新作业进行更新,因为它只是引用作业,而不是存储实体本身。大!但是现在比较删除功能的结果:
"jobs"
此查询的结果可以是任何值。阿波罗不知道您刚刚删除了具有特定ID的作业。也许GraphQL在规范中包含神奇的“ __isDeleted”之类的东西,我们会得到类似的东西:
{
"data": {
"deleteJob": {
"returning": {
"id": 2,
}
}
}
}
我们可以给我们的缓存实现一个提示,即应从所有引用查询中删除带有{
"data": {
"deleteJob": {
"__typename": "Job",
"__isDeleted": true,
"id": 2,
}
}
}
}
的实体。但是不幸的是这并不存在。不过,这还不错,我们可以使用__isDeleted: true
来触发其他查询的重新提取,也可以manually update the other query:
refetchQuery