Apollo为何未将GetPayableQuery响应合并至缓存?
GraphQL单条查询结果未合并到列表缓存的问题
问题
调用GetPayableQuery获取单条应付发票数据后,原本预期该数据会自动合并到GetPayablesQuery的列表缓存中,但实际没有生效。
相关代码
两个查询定义
const GetPayablesQuery = gql` query GetPayableInvoicesQuery( $paging: PagingGqlInputOfPayableInvoiceSortColumnGqlInput! $teamId: HashId! $filter: PayableInvoiceQueryFilterInput ) { team(teamId: $teamId) { payableInvoices(paging: $paging, filter: $filter) { items { ...PayableInvoiceFields } numPages pageNum pageSize totalCount } } } ${PayableInvoiceFieldsFragment} `; const GetPayableQuery = gql` query GetPayableInvoiceQuery($payableInvoiceId: HashId!, $teamId: HashId!) { team(teamId: $teamId) { payableInvoice(payableInvoiceId: $payableInvoiceId) { ...PayableInvoiceFields } } } ${PayableInvoiceFieldsFragment} `;
共用的Fragment
const PayableInvoiceFieldsFragment = gql` fragment PayableInvoiceFields on PayableInvoice { amount attachments { pageFiles url } canCancel canMarkAsPaid canPayNow canChangePaymentSource currency dueDate fundingSource { id mask name type } id invoiceNumber issueDate paymentDate paymentOptionRowVersion { value } rowVersion { value } status vendor { name email id } } `;
原因及解决办法
- 缓存机制的独立性:多数GraphQL客户端(比如Apollo Client)会把单个对象缓存和列表查询缓存分开存储。单个
PayableInvoice对象的缓存更新后,列表查询的缓存不会自动同步,因为列表缓存是带有分页、过滤参数的独立条目。 - 手动更新列表缓存:在
GetPayableQuery执行完成后,手动将结果合并到对应的列表缓存中。可以通过client.writeQuery方法,找到匹配teamId、分页及过滤参数的列表缓存条目,把新数据添加到items数组(如果不存在)或者替换已有条目。 - 配置缓存策略:通过客户端的
typePolicies配置,让列表字段能自动关联单个对象的更新。比如确保PayableInvoice类型的keyFields设置为id,然后给team类型的payableInvoices字段配置merge函数,处理新数据的合并逻辑。 - 使用refetchQueries:在调用
GetPayableQuery时,指定refetchQueries参数重新执行GetPayablesQuery,强制刷新列表缓存,但这种方式会额外发起请求,不如手动更新高效。
内容的提问来源于stack exchange,提问作者Mark Steggles
相关产品推荐
相关产品推荐

