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 matchercacheRedirects(以前叫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  | const { todo } = client.readQuery({  | 
readFragment, 读取已有数据的片段, 如果某个字段不存在则报错
1  | const todo = client.readFragment({  | 
writeFragment和writeQuery, 用法和read差不多, 除了需要多一个参数data:
1  | client.writeFragment({  | 
忽略cache
有两者情况可能需要绕过缓存, 一种是想直接访问后端然后写入缓存, 另一种是完全不使用缓存(适合敏感信息).
1  | client.query({  | 
mutation后cache的更新
refetchQueries是mutation后更新cache的简单方法, 但是它会从后端再做一次请求而显得不那么优秀. Mutation组件有一个updateprop可以用于手动更新cache, 而不用重新fetch.
1  | import CommentAppQuery from '../queries/CommentAppQuery';  | 
- Title: Apollo client的缓存机制
 - Author: Kopei
 - Created at : 2019-04-08 00:00:00
 - Updated at : 2025-08-13 18:15:58
 - Link: https://kopei.github.io/2019/04/07/frontend-2019-04-09-apollo-cache/
 - License: This work is licensed under CC BY-NC-SA 4.0.
 
        Comments