我目前正在一个项目中介绍Apollo,我对缓存/ gql组件组合有一些疑问。
我将使用一个例子来解释:假设我们有一个<Widget>
组件&#34; eced&#34;用gql查询定义它的数据要求,这是一个很长的列表。此组件没有<ApolloProvider>
,因为它不是独立使用的 - 它必须使用<ApolloProvider>
在其他组件中呈现。然后我有两个应用程序,使用此组件:<SimpleApp>
和<ComplexApp>
。当<SimpleApp>
呈现<Widget>
时,后者只是下载数据,一切都很好。但是,<ComplexApp>
已经拥有<Widget>
使用的部分数据。我希望<Widget>
能够解决这个问题并仅下载缺少的数据,而不是下载其查询中定义的整个数据集。这里的业务逻辑将检查Apollo商店中已有的内容,并从<Widget>
的查询中删除这些字段。
查询的形式为:
query WidgetQuery {
someType {
id
a
b
c
d
}
}
query ComplexAppQuery {
someType {
b
c
}
}
因此当<Widget>
位于<ComplexApp>
内时,我不会喜欢下载&#34; a&#34;和&#34; d&#34;,但是否则是。
我有什么方法可以实现这一点,自定义解析器是正确的方法吗?
答案 0 :(得分:0)
您可以使用@skip
和@include
指令来实现此目标,这些指令基于从其父<Widget>
或<SimpleApp>
传递的<ComplexApp>
组件的道具零件。让我们调用道具all
:
<SimpleApp>
<Widget all={true}/>
</SimpleApp>
<ComplexApp>
<Widget all={false}>
</ComplexApp>
由于Apollo客户端通常使用id
和__typename
(自动添加到每个查询中)来标识节点,因此您还需要包含id
。所以Query看起来像这样:
query widgetQuery($all: Boolean!) {
someType {
id
a @include(if: $all)
b
c
d @include(if: $all)
}
}
仅当传递的a
变量为d
时才会包含<{$all
和true
。
在Apollo中,您可以通过将带有一个参数的函数传递给查询的options
来将props传递给变量:
const widgetQuery = gql`
query widgetQuery($all: Boolean!) {
someType {
id
a @include(if: $all)
b
c
d @include(if: $all)
}
}
`
const WidgetWithQuery = graphql(widgetQuery, {
options: (ownProps) => ({
variables: {
all: ownProps.all
}
})
})(Widget)
现在,Apollo客户端确保根据SimpleApp
将来自ComplexApp
和id
的所有获得字段合并到一个给定节点。
有关详细信息,请查看this interactive tutorial关于@skip
和@include
。