Apollo Boost嵌套查询返回Null问题排查求助
我在使用React Apollo 2.1执行一个包含三层嵌套的GraphQL查询时遇到了问题:在GraphiQL中执行该查询能正常返回所有字段数据,但在React应用中调用查询时,除嵌套字段外其余字段均正常返回,嵌套的locate和address字段却返回Null。以下是相关代码,恳请提供排查思路?
查询定义
export const mapDeviceQuery = gql` query mapDeviceQuery($input: String, $type: DeviceSearchEnum) { devices(input: $input, type: $type) { id client productKey alias imei subFleet warranty isActive locate{ latitude longitude speed heading date time } address{ full street_address city state zip } } } `
DeviceList组件代码
// deviceList.hoc.js render = ({loading, error, data} = this.props) => { let deviceList = []; if(data.devices){ console.log(data.devices); for(let i=0; i<data.devices.length; i++){ if(data.devices[i].isActive){ let d = data.devices[i]; deviceList.push({ key : i, alias : d.alias, driver : d.driver, subFleet : d.subFleet, imei : d.imei, address : d.address.full, date : d.locate.date, time : d.locate.time }); } } }
查询连接器代码
// queryconnector.js import React, { Component } from 'react'; import { Query } from "react-apollo"; const queryConnector = (queryGQL) => WrappedComponent => { class QueryConnector extends Component { render = () => { return ( <Query query={queryGQL}> {({ loading, error, data }) => { console.log(loading) console.log(data) return ( <WrappedComponent runQuery={queryGQL} loading={loading} error={error} data={data} {...this.props} /> ) }} </Query> ) } } return QueryConnector } export default queryConnector
排查思路
先确认服务器是否真的返回了嵌套字段
打开浏览器开发者工具的Network面板,找到Apollo发送的GraphQL请求,查看响应体里的devices数组,确认每个设备的locate和address字段是否有实际值。有时候GraphiQL的请求参数(比如$input和$type)和应用里的不一致,导致服务器返回的嵌套字段为空,这时候要核对请求参数是否和GraphiQL测试时一致。检查Apollo缓存的匹配问题
Apollo Client会根据字段名和参数缓存数据,如果嵌套字段的返回结构和查询定义有细微差异(比如大小写、字段名拼写),缓存可能无法正确映射。可以临时给Query组件加上fetchPolicy="no-cache"属性,关闭缓存后再测试:<Query query={queryGQL} fetchPolicy="no-cache">如果关闭缓存后嵌套字段正常显示,那就是缓存的字段匹配问题,需要检查缓存的配置或者字段的一致性。
核对查询字段的拼写和层级
仔细对比GraphiQL中使用的查询和代码里的mapDeviceQuery,确保嵌套字段的名称、层级完全一致——比如有没有把locate写成location,或者address.full在服务器返回里是不是叫address.fullAddress之类的。有时候复制代码时容易出现拼写错误。检查组件中数据访问的安全性
在你的组件代码里,直接访问d.address.full和d.locate.date,如果address或locate本身是Null,会导致报错,但你说这些字段返回Null,那可以在循环里单独打印每个设备对象:console.log("Device data:", d);看看
d.address和d.locate的实际值,确认是Apollo没拿到数据,还是服务器确实返回了Null。排查Apollo Client的本地Schema或解析器
如果你在Apollo Client中配置了本地类型定义(TypeDefs)或自定义解析器,这些本地逻辑可能干扰了嵌套字段的解析。可以暂时移除本地的Schema和解析器配置,看看问题是否消失。考虑版本兼容性问题
React Apollo 2.1是比较旧的版本,可能存在嵌套字段解析的已知bug。可以尝试升级到该系列的最新小版本(比如2.1.x的最后一个稳定版),或者查看官方文档的历史issue,看看有没有类似的问题记录。
内容的提问来源于stack exchange,提问作者Jeff Winkler

