React Native Apollo Client.query无法从App Sync-DynamoDB获取更新数据
我帮你排查下代码里的问题,主要有几个关键点导致你拿不到服务器新数据:
1. client.query 的参数格式错误
你在 someMethod 里调用 this.props.client.query 时,错误地把 fetchPolicy 嵌套在了 options 对象里,但 Apollo Client 的 query 方法并不接受这样的嵌套结构。这直接导致你设置的 network-only 策略根本没生效,查询还是沿用了默认的缓存策略,自然拿不到服务器的新数据。
修正后的 someMethod 代码:
someMethod = () => { this.props.client.query({ query: ListSubjects, // 直接把配置放在顶层,不要嵌套在options里 fetchPolicy: 'network-only', // 注意:Apollo Client 中没有 cachePolicy 这个配置项,若无需额外缓存控制可直接移除 }).then(({ data }) => { console.log(data.listSubjects); this.props.client.writeQuery({ query: ListSubjects, data, }); }); }
2. 确认 writeQuery 的数据结构完全匹配查询
当你调用 writeQuery 更新缓存时,必须确保传入的 data 结构和 ListSubjects 查询的返回结构完全一致,包括 Apollo 自动生成的 __typename 字段(规范化缓存依赖这个字段识别数据)。如果结构不匹配,缓存不会被正确更新,graphql 高阶组件依然会读取旧的缓存数据。
你可以在 then 回调里打印完整的 data 对象,和组件挂载时 graphql 高阶组件拿到的数据结构做对比,确保没有差异。
3. 检查查询变量的一致性
如果你的 ListSubjects 查询需要传入变量(比如分页参数、筛选条件),那在手动调用 client.query 和 writeQuery 时,必须传入和 graphql 高阶组件完全相同的变量。因为 Apollo Client 的缓存是按「查询 + 变量」作为唯一键存储的,变量不匹配的话,你更新的是另一个缓存条目,高阶组件还是会读取原来的缓存数据。
比如如果高阶组件的查询带了变量:
graphql(ListSubjects, { options: { fetchPolicy: 'cache-and-network', variables: { page: 1, limit: 10 } // 假设带了变量 }, // ... })
那手动查询时也要带上相同的变量:
this.props.client.query({ query: ListSubjects, fetchPolicy: 'network-only', variables: { page: 1, limit: 10 }, // 必须和高阶组件的变量一致 })
同时 writeQuery 也要带上变量:
this.props.client.writeQuery({ query: ListSubjects, variables: { page: 1, limit: 10 }, data, });
4. 关于 cache-and-network 的补充说明
你给 graphql 高阶组件设置的 cache-and-network 策略是没问题的,它会先返回缓存数据,再异步请求服务器更新缓存。但手动查询时如果策略没生效,就不会触发缓存更新,所以修正第一步的参数格式是关键。
按照上面的步骤调整后,再测试调用 someMethod 应该就能拿到服务器的最新数据,并且正确更新缓存,让组件 props 同步更新了。
内容的提问来源于stack exchange,提问作者Naveen Vignesh

