Next.js搭配Apollo GraphQL调用cache.readQuery始终返回null问题求助
问题排查与解决方案
核心原因
你遇到的cache.readQuery返回null,主要有以下几个常见原因:
- 缓存key匹配失败:Apollo Client的缓存key是由查询语句+查询参数共同生成的,你在
readQuery时没有传入LIST_JOBS对应的查询参数,和列表页useQuery(LIST_JOBS)调用时的参数不一致,无法匹配到已有的缓存条目。如果你的列表页调用LIST_JOBS时没有传任何参数,那你后续writeQuery时传入variables: { input: newTask.type }也会导致写入的缓存和列表页的查询不匹配,列表页无法读取到更新后的数据。 - 缓存条目不存在:如果用户先访问发布页、从未进入过列表页,列表页的
LIST_JOBS查询从未触发过,缓存中没有对应条目,readQuery自然返回null。 - 字段名不匹配:你从缓存读取时取的是
data.jobs,写入时却用了tasks作为根字段,字段名不一致即使读取成功后续也会出现异常。
修复方案
1. 统一查询参数
保证readQuery、writeQuery使用的参数和列表页useQuery(LIST_JOBS)的参数完全一致:
- 如果列表页调用
LIST_JOBS没有传参数,那读写缓存时都不要加variables参数 - 如果列表页调用
LIST_JOBS传了参数,那读写缓存时必须传入完全相同的参数
2. 增加缓存兜底逻辑
处理缓存不存在的场景,避免解构报错
3. 统一字段名
读写缓存的根字段和LIST_JOBS定义的返回根字段保持一致
修正后代码示例
const updateCache = (cache: any, mutationResult: any) => { const newTask = mutationResult.data.createJob; // 此处参数和列表页useQuery(LIST_JOBS)的参数完全保持一致 // 如果列表页没传参,直接删掉variables配置即可 const queryVariables = { input: newTask.type }; // 读取缓存增加兜底 const cacheData = cache.readQuery({ query: LIST_JOBS, variables: queryVariables }) || { jobs: [] }; cache.writeQuery({ query: LIST_JOBS, variables: queryVariables, // 字段名和LIST_JOBS返回的根字段统一,此处假设为jobs data: { jobs: [...cacheData.jobs, newTask] } }) }
额外注意事项
- 调整
CREATE_JOBmutation的返回字段,和LIST_JOBS中单个job的返回字段保持一致,避免缓存字段缺失导致列表页渲染异常 - 可以借助Apollo Client Devtools工具查看缓存中的已有条目,确认查询参数和字段名,避免匹配错误
内容的提问来源于stack exchange,提问作者Explorer
相关产品推荐
相关产品推荐

