Apollo 3.0如何通过typePolicies填充客户端Schema?
Apollo Client 3.x 本地状态typePolicies配置后查询返回异常
客户端Schema定义
const typeDefs = gql` extend type Query @client { getMessageSliceByIdMessaging(id_messaging: String!): [MESSAGE_SLICE]! } type MESSAGE_SLICE { _id: String! __typename: String! newest_date_creation: String! oldest_date_creation: String! list_id_message: [MESSAGE]! } `
InMemoryCache的typePolicies配置
typePolicies: { Query: { fields: { getMessageSliceByIdMessaging : { merge(existing = [], incoming = [], {cache}) { // 执行自定义逻辑 return some_shenanigans }, read(existing = []) { return [...existing] // existing能正确返回merge生成的some_shenanigans }, } } } }
查询与数据写入代码
MESSAGE_SLICE片段
const MESSAGE_SLICE_FRAGMENT = gql` fragment MessageSliceFragment on MESSAGE_SLICE { _id newest_date_creation oldest_date_creation list_id_message { ...messageFragment } } ${MESSAGE_FRAGMENT} `
获取MESSAGE_SLICE列表的查询
const GET_MESSAGE_SLICE_BY_ID_MESSAGING = gql` query getMessageSliceByIdMessaging ( $id_messaging: String! ) { getMessageSliceByIdMessaging @client ( id_messaging: $id_messaging ) { ...MessageSliceFragment } } ${MESSAGE_SLICE_FRAGMENT} `
查询调用与数据写入
// 调用查询 const messageSliceListData = useQuery(GET_MESSAGE_SLICE_BY_ID_MESSAGING, { variables: { id_messaging: route.id_messaging, }, }) // 写入数据到缓存 await client.writeQuery({ query: GET_MESSAGE_SLICE_BY_ID_MESSAGING, variables: { id_messaging, }, data: {getMessageSliceByIdMessaging: [...SOME_ARRAY_DATA_THAT_NEED_TO_BE_MERGE_IN_THE_TYPE_POLICIES]} })
问题现象
messageSliceListData?.data始终返回[{}]或undefined,无任何报错。
已尝试的解决方法
- 使用
toReference将some_shenanigans作为引用返回; - 直接返回
some_shenanigans原始数据。
正确实现方案
- 配置keyArgs区分缓存条目
由于查询依赖id_messaging变量,必须在typePolicies中指定keyArgs,让Apollo根据变量值区分不同的缓存条目,否则所有查询会共用同一个缓存,导致数据异常:
typePolicies: { Query: { fields: { getMessageSliceByIdMessaging : { keyArgs: ["id_messaging"], // 关键:根据id_messaging区分缓存 merge(existing = [], incoming = [], {cache}) { // 自定义合并逻辑,确保返回的数组每个元素都符合MESSAGE_SLICE结构 return some_shenanigans; }, read(existing = []) { return existing; // 无需额外复制,直接返回即可 }, } } } }
- 确保数据结构完整性
合并后返回的some_shenanigans数组中,每个MESSAGE_SLICE对象必须包含:
- 正确的
__typename: "MESSAGE_SLICE"字段; - Schema定义的所有必填字段(
_id、newest_date_creation等); list_id_message中的每个MESSAGE对象同样需要包含__typename和唯一标识字段(如_id),否则缓存无法解析,会返回空对象{}。
- 验证writeQuery的变量匹配
调用writeQuery时,传入的variables必须与查询定义的变量完全一致,确保缓存能正确关联到对应条目中。
内容的提问来源于stack exchange,提问作者Ludivin Divin
相关产品推荐
相关产品推荐

