Apollo client的缓存机制
Apollo client2.0的缓存实现
Apollo client2.0
使用apollo-client-inmemory
作为客户端数据的缓存实现, 主要使用包中的InMemoryCache
作为data store
来缓存数据. InMemoryCache
除了作为客户端缓存的功能外, 还有一个好处是只有当遵循特定的标识符规则(给缓存加特定的id), 每次对后端做mutation
后可以自动更新缓存.
InMemoryCache
的配置
引入cache:
1 | import {InMemoryCache} from 'apollo-client-inmemory'; |
InMemoryCache
的构造器可以有如下配置:
addTypename: boolean
, 指定是否需要在document
中添加__typename, 默认为true.dataIdFromObject
, 由于InMemoryCache
是会normalize
数据再存入store
, 具体做法是先把数据分成一个个对象, 然后给每个对象创建一个全局标识符_id
, 然后把这些对象以一种扁平的数据格式存储. 默认情况下,InMemoryCache
会找到__typename
和边上主键id
值作为标识符_id
的值(如__typename:id
). 如果id
或者__typename
没有指定, 那么InMemoryCache
会fall back
查询query
的对象路径. 但是我们也可以使用dataIdFromObject
来自定义对象的唯一表示符:
1 | import { InMemoryCache, defaultDataIdFromObject } from 'apollo-cache-inmemory'; |
fragmentMatcher
,fragment matcher
默认使用heuristic fragment matcher
cacheRedirects
(以前叫cacheResolvers
,customResolvers
), 在发出请求之前将查询重定向到缓存中的另一个条目的函数映射。
自动缓存更新
假设我们有一个query:
1 | { |
然后我们再做一个mutation
1 | mutation { |
如果保持这个id
匹配, 每次更新都会自定更新data store
中score
字段的数据, 如果query有多个字段, 那么只要mutation的结果数据尽量保持更新前一次的query的数据一致, 就可以利用上诉特点保持cache的数据鲜活.
和Cache直接交互
可以使用apollo client的类方法直接对cache做读写操作. 方法有: readQuery
, readFragment
, writeQuery
,writeFragment
.
readQuery
, 从cache中读取数据, 有一个字段没有存在则会报错.1
2
3
4
5
6
7
8
9
10
11
12
13
14const { todo } = client.readQuery({
query: gql`
query ReadTodo($id: Int!) {
todo(id: $id) {
id
text
completed
}
}
`,
variables: {
id: 5,
},
});readFragment
, 读取已有数据的片段, 如果某个字段不存在则报错1
2
3
4
5
6
7
8
9
10const todo = client.readFragment({
id: '5',
fragment: gql`
fragment myTodo on Todo {
id
text
completed
}
`,
});writeFragment
和writeQuery
, 用法和read差不多, 除了需要多一个参数data
:1
2
3
4
5
6
7
8
9
10
11client.writeFragment({
id: 'typename:5', //复合键用于表示cache中数据
fragment: gql`
fragment myTodo on Todo {
completed
}
`,
data: {
completed: true,
},
});
忽略cache
有两者情况可能需要绕过缓存, 一种是想直接访问后端然后写入缓存, 另一种是完全不使用缓存(适合敏感信息).
1 | client.query({ |
mutation后cache的更新
refetchQueries
是mutation后更新cache的简单方法, 但是它会从后端再做一次请求而显得不那么优秀. Mutation组件有一个update
prop可以用于手动更新cache, 而不用重新fetch.
1 | import CommentAppQuery from '../queries/CommentAppQuery'; |
- Post title:Apollo client的缓存机制
- Post author:Kopei
- Create time:2019-04-08 00:00:00
- Post link:https://kopei.github.io/2019/04/07/frontend-2019-04-09-apollo-cache/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments