因此,如果没有您的架构类型定义,您的问题很难回答。但是让我们假设它是这样的:
type Query {
menus: Menus
}
type Menus {
menuA: Menu
menuB: Menu
}
警告本质上是说没有任何keyArgs Apollo Cache 无法规范化menus 查询。从他们的角度记住 - 你有一个 single menus root 查询。 (即GerMenuA 和GerMenuB 是客户端查询而不是root 查询)。
(旁注 - 因为您没有 id 字段,请参阅 disabling normalization。)
选项 1:分离您的查询
type Query {
menuA: Menu
menuB: Menu
}
Apollo 缓存现在将 menuA 和 menuB 存储为单独的查询。如果您想安全起见,可以设置类型策略:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
},
Query: {
fields: {
menuA: {
keyArgs: false
},
menuB: {
keyArgs: false
}
}
}
},
});
keyFields: false 告诉 AC 将 Menu 存储在它的父查询下。 keyArgs: false 表示 menuA 和 menuB 都是单例查询。缓存策略将默认为merge: false,以便现有数据将被传入的数据替换。
选项 2:定义查询参数
在此选项中,您将 name 参数添加到您的 menus 查询中:
type Query {
menus(name: String): Menu
}
默认情况下,缓存会为您在查询特定字段时提供的每个唯一参数值组合存储一个单独的值。
Apollo 缓存现在将 menus:{name:menuA} 和 menus:{name:menuB} 存储为单独的缓存对象。同样,如果您想安全起见,可以设置类型策略:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
}
},
});
同样,缓存策略将默认为merge: false,以便现有数据将被传入的数据替换。
选项 3:定义合并策略
我们已经讨论了为什么现有架构会令 Apollo Cache 感到困惑。但如果你真的准备好了,剩下要做的就是定义一个合并策略:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
},
Menus: {
keyFields: false,
merge: true
},
Query: {
fields: {
menus: {
keyArgs: false,
merge: true
}
}
}
},
});
merge: true 告诉 Apollo Cache 将 GerMenuA 和 GerMenuB 的结果合并到具有 menuA 和 menuB 属性的单个 Menus 缓存对象中。每次运行查询时如果没有它,您会破坏前一个查询的结果。