React Apollo缓存读取报错:无法解构null的skills属性
解决Apollo Client缓存读取null导致解构失败的问题
问题分析
你遇到的TypeError: Cannot destructure property 'skills' of 'cache.readQuery(...)' as it is null,本质是调用cache.readQuery({ query: QUERY_SKILLS })时返回了null,无法解构出skills字段。常见触发原因:
- QUERY_SKILLS查询从未执行过,缓存中无对应数据
- 调用readQuery时传入的变量与QUERY_SKILLS实际执行时的变量不匹配,无法命中缓存条目
- 缓存数据结构与QUERY_SKILLS的查询结构不匹配
可行解决方案
1. 先判断缓存结果再解构
在解构前先校验readQuery的返回值,用可选链或默认值处理null情况:
const existingSkillsData = cache.readQuery({ query: QUERY_SKILLS }); // 用可选链+默认空数组避免解构失败 const skills = existingSkillsData?.skills || []; // 执行缓存更新 cache.writeQuery({ query: QUERY_SKILLS, data: { skills: [...skills, newSkill] } });
2. 确保QUERY_SKILLS已提前执行
如果SkillForm组件渲染时,QUERY_SKILLS还没被执行过,缓存自然为空。可以在父组件或SkillForm内部先通过useQuery(QUERY_SKILLS)获取数据,等待数据加载完成后再渲染表单:
// 在SkillForm组件内 const { loading, data } = useQuery(QUERY_SKILLS); if (loading) return <div>加载中...</div>; // 渲染表单 return <form onSubmit={handleSubmit}>...</form>;
3. 匹配readQuery的变量参数
如果QUERY_SKILLS是带变量的查询(比如分页、筛选),调用readQuery时必须传入与之前执行查询完全一致的变量,否则无法命中缓存:
// 假设QUERY_SKILLS执行时用了这些变量 const queryVariables = { page: 1, limit: 10 }; const existingSkillsData = cache.readQuery({ query: QUERY_SKILLS, variables: queryVariables });
4. 使用cache.modify直接修改缓存
相比readQuery+writeQuery的组合,cache.modify可以直接操作缓存字段,无需先读取整个查询结果,从根源避免null问题:
cache.modify({ fields: { // existingSkills默认设为空数组,防止初始无数据时出错 skills(existingSkills = []) { // 将新技能写入缓存片段 const newSkillRef = cache.writeFragment({ data: newSkill, fragment: gql` fragment NewSkillFragment on Skill { id name // 包含Skill类型的所有必要字段 } ` }); // 返回更新后的技能数组 return [...existingSkills, newSkillRef]; } } });
额外注意
更新QUERY_ME缓存时,同样要遵循上述原则:要么提前校验readQuery结果,要么用cache.modify处理,避免同样的解构错误。
内容的提问来源于stack exchange,提问作者UniKern
相关产品推荐
相关产品推荐

