Apollo 客户端缓存查询结果,然后在某些情况下使用此缓存来解析查询。你可以通过配置查询数据时使用的
fetchPolicy
来控制此行为。但是,如果我们的缓存中的信息过时会发生什么?如果服务端的信息发生变化,我们如何确保更新缓存?我们的UI将如何更新以反映这些新信息的变化?本节将尝试解答这些问题。
你可以设置一些策略,以确保 Apollo 客户端最终与服务端可用的信息保持一致。比如:手动查询,轮询查询和GraphQL订阅。
Refetch
Refetch
是强制部分缓存响应服务端可用信息的最简单方法。本质上,refetch 强制执行一个查询,立即再次请求服务端,绕过缓存。此查询的结果与所有其他查询结果一样,可更新缓存中可用的信息,从而更新页面上的所有查询结果。
例如,在 GitHunt 项目中,我们可能有如下组件实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React, { Component } from 'react' ;
import { graphql, gql } from 'react-apollo' ;
class Feed extends Component {
onRefreshClicked() {
this .props.data.refetch();
}
}
const FeedEntries = gql`
query FeedEntries($type: FeedType!, $offset: Int, $limit: Int) {
feed($type: NEW, offset: $offset, limit: $limit) {
createdAt
commentCount
score
id
respository {
# etc.
}
}
}
`;
const FeedWithData = graphql(FeedEntries)(Feed);
假设我们在页面上有一个“刷新”按钮,当该按钮被点击时,在我们的组件上调用
onRefreshClicked
方法。我们有一个方法
this.props.data.refetch
,它允许我们重新获取与
feed
组件相关联的查询。这意味着,不会从缓存中解析有关
feed
字段的信息,因此查询请求将直接到达服务端,并使用新的结果更新缓存。
如果服务端有某种更新(例如,添加到 Feed 中的新代码仓库),Apollo 客户端的 store 将获得更新,UI将根据需要重新呈现。
何时 refetch
为使 refetch 策略成功,你需要知道何时重新获取查询,所幸 refetch 的使用场景很少。
手动刷新
:许多应用程序提供一种方式让用户通过刷新按钮或下拉手势手动请求更新其数据视图,
refetch
非常适合这种情况。
响应事件
:有时,你知道事件何时发生,将有可能会使数据无效。例如,你可能会有某种事件推送机制,告诉你数据可能已更改。因此,
refetch
是可以避免不必要的轮询的最佳方式。
突变后
:Apollo 提供了
一些方法
,以确保 store 在突变后是最新的,但最简单的方法是完全重新读取相关查询。在这种情况下,除了在查询本身使用
refetch
方法之外,还可以使用
refetchQueries
选项执行突变。
但是,在某些情况下,响应用户输入或更改 UI 的变更并无必要,例如,如果某些
其他
用户决定将代码仓库插入到 GitHunt Feed 中,并且我们需要展示这条数据。我们的客户不知道这已经发生了,直到刷新页面才会看到新的 Feed 项。该问题的解决方案之一便是轮询。
如果你的查询结果可能会频繁变更,并且你想要查看相对较新的视图,则可以考虑轮询。轮询在特定的时间间隔内被触发,与 refetch 相似。
继续我们的 refetch 示例,我们可以通过在查询中添加一个选项来添加轮询间隔:
1
2
3
const FeedWithData = graphql(FeedEntries, {
options : { pollInterval : 20000 },
})(Feed);
查询的
pollInterval
选项设置该查询将被重新执行的时间间隔(以毫秒为单位)。在上述例子中,Apollo 会每隔二十秒处理一次这个查询,确保你的UI在任何时刻都只有20秒过时。
一般来说,你的轮询间隔不应小于10秒,否则容易对你的服务器造成大量负载。如果你需要立即在 UI 中反映数据变化,则应使用
GraphQL 订阅
。
博客文章
找到该主题。