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 | 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组件有一个update
prop可以用于手动更新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