Apollo Client Cache:如何在Modifier中合并数据
Apollo缓存Modifier正确使用指南:合并新旧数据
原方案的问题
你直接扩展prevData(Reference类型)的做法不可靠,因为Reference只是缓存中实体的指针,它包含__typename和__ref(实体缓存ID),但并不存储实体的实际字段数据。直接给Reference对象添加someField不会被Apollo缓存识别,这个修改会被直接丢弃,不会作用到实际的实体数据上。
为什么details.readField返回undefined
你之前用details.readField(details.storeFieldName)返回undefined,是因为缺少了第二个关键参数——要读取的实体引用。正确的用法是:第一个参数是目标字段名,第二个参数是Reference对象(即prevData),这样Apollo才会找到引用指向的实体并读取对应字段:
const originalValue = details.readField('someField', prevData);
如果还是返回undefined,可能是该字段在实体中不存在,或者实体本身未被缓存。
正确的缓存更新方式
要实现新旧数据合并,你需要先读取Reference指向的实体完整数据,修改后写回缓存,具体代码如下:
import { gql } from '@apollo/client'; const myModifier: Modifier<Reference> = (prevData, details) => { // 从Reference获取实体的缓存ID和类型 const entityId = prevData.__ref; const entityTypename = prevData.__typename; // 读取实体的当前数据(按需指定需要保留的字段) const currentEntity = details.cache.readFragment({ id: entityId, fragment: gql` fragment EntityData on ${entityTypename} { someField # 这里列出所有需要保留的其他字段 } ` }); if (!currentEntity) return prevData; // 实体不存在时返回原引用 // 合并新旧数据,更新目标字段 const updatedEntity = { ...currentEntity, someField: 'updatedValue' }; // 将修改后的实体写回缓存 details.cache.writeFragment({ id: entityId, fragment: gql` fragment UpdatedEntityData on ${entityTypename} { someField } `, data: updatedEntity }); // 返回原Reference,因为字段本身仍指向该实体,我们修改的是实体内容 return prevData; };
关键注意事项
- 不要直接修改Reference对象,它只是实体的指针,不是数据容器
- 必须通过
readFragment/writeFragment操作实体的实际数据 - 如果你的Modifier是用于修改字段的返回值(而非实体本身),可以直接返回修改后的实体对象,但通常缓存中实体类型字段会以Reference存储,返回Reference更符合缓存规范
内容的提问来源于stack exchange,提问作者NotX
相关产品推荐
相关产品推荐

