reactjs - React Apollo 在突变后更新客户端缓存
问题描述
成功执行突变后,我正在尝试更新我的 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"
}
}."
在我的客户端缓存中,我可以看到
data{data{DojoType {...WITH ALL DATA INSIDE APPART FROM THE NEW DISZIPLINE}}
和
data{data{DisziplineType {THE NEW OBJECT}}
Web 上的客户端缓存似乎存在很多混淆。不知何故,提出的解决方案都没有帮助,或者对我没有任何意义。任何帮助将不胜感激。
编辑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)
仍然是未定义的。有什么建议吗?
解决方案
所以我认为您的实际错误是您必须将 ID 作为字符串提供:variables: {id: id.toString()}
。你可以看到这两行是不同的:
dojo({\"id\":1})
dojo({\"id\":\"1\"})
但我强烈建议使用提供的 IDreadFragment
代替readQuery
并更新 dojo。这也应该更新查询以及所有查询中出现的所有其他 dojo。readFragment
您可以在此处找到文档。
另一个技巧也是简单地返回整个 dojo 以响应突变。我会说人们应该少担心这一点,并且不要做太多的缓存更新,因为缓存更新是你的 API 的隐式行为,在你的类型系统中没有。可以在该disziplins
字段中找到新的 disziplin 现在已在您的前端编码。想象一下,您想在此处添加另一个步骤,其中必须先批准新的 disziplins 才能最终进入那里。如果突变返回整个道场,一个简单的后端更改就可以完成这项工作,您的客户不必知道这种行为。
推荐阅读
- angular - 带有 Angular 6 的基于 MS Office JS 的 Word 插件
- sql - 检索具有特定值的最新记录
- java - JDK 1.8(C:\...)没有附加IDEA注解,有些问题会找不到
- python - 使用Python获取列的两个值之间的行
- css - angular-dual-listbox - 隐藏按钮
- flexbox - Vuetify - Flexbox - 错误的弹性行设置
- jquery - 当数据较少时,读取较少的文本 css 更改
- fpga - Lattice ICE5LP4K FPGA:如何将 HFOSC 添加到用户 vhdl
- c# - 单击单元格时列表视图更改图标
- properties - 将 NSArray 设置为自定义类的属性