GraphQL/Apollo多查询缓存清理及相关技术问题咨询
Apollo Client 缓存操作与组件渲染问题解答
问题1:能否通过一次client.readQuery调用读取多个查询的缓存?若不能,readQuery是否为同步执行?
- 不能,
readQuery每次只能读取单个查询对应的缓存数据,调用时必须指定唯一的query和匹配的variables(如果查询需要变量)。要读取多个查询的缓存,需要多次调用readQuery,分别传入不同的查询和变量。 readQuery是同步执行的,它直接从内存中的Apollo Cache读取数据,不会发起网络请求,可直接获取返回结果,无需异步处理。
示例中读取多个查询的写法:
update: (store: DataProxy, data: FetchResult<?*>) => { // 读取第一个查询的缓存 const cacheData1 = store.readQuery({ query: GETQUERY1, variables: { v: "str" }, }); // 读取第二个查询的缓存 const cacheData2 = store.readQuery({ query: GETQUERY2, variables: { id: 123 }, }); }
问题2:读取查询缓存后,如何清理(而非更新)该缓存?
Apollo Cache没有直接删除单条查询缓存的API,但可以通过以下几种方式实现类似"清理"的效果:
- 方式1:用
writeQuery写入空数据:根据GraphQL Schema结构,将对应查询的缓存数据设为空值(比如空数组、null),覆盖原有缓存。例如:update: (store: DataProxy, data: FetchResult<?*>) => { store.writeQuery({ query: GETQUERY1, variables: { v: "str" }, // 假设GETQUERY1返回列表,写入空数组清空缓存 data: { getItems: [] } }); } - 方式2:用
evict删除特定缓存条目:如果知道缓存数据的路径,可直接移除对应的字段或对象,最后调用gc()清理无引用的缓存对象。比如删除根查询下的getItems字段:update: (store: DataProxy, data: FetchResult<?*>) => { store.evict({ fieldName: 'getItems', variables: { v: "str" } // 匹配查询时的变量 }); store.gc(); } - 方式3:重置整个缓存:如果需要清空所有缓存,可以调用
client.resetStore(),但这会清除所有查询的缓存,适合全局重置场景。
问题3:查询的缓存更新或useMutation中的refetchQueries操作,是否会强制调用该查询的所有组件重新渲染?
是的。
- 当你通过
writeQuery/evict等方式更新缓存中某条查询的数据时,所有使用useQuery(或其他Apollo查询钩子)订阅该查询(且变量匹配)的组件,都会因缓存数据变化重新渲染。 refetchQueries会重新执行指定的查询,将新结果写入缓存,这同样会触发所有依赖该查询的组件重新渲染——因为缓存中的数据被替换,组件订阅的数据源发生了变化。
内容的提问来源于stack exchange,提问作者Hongli Bu
相关产品推荐
相关产品推荐

