如何映射含Union与Fragment的GraphQL查询并实现页面渲染
处理GraphQL Union类型的查询结果与React渲染
首先,你已经通过Fragment和别名正确获取了数据,现在需要利用GraphQL返回的__typename字段来区分CUSTOM_ATTRIBUTES Union中的不同类型,然后针对性地访问对应的字段。另外,因为custom_attributes是一个数组,确实需要嵌套map来遍历每个属性项。
核心要点:
- GraphQL Union类型的每个返回项都会自带
__typename字段,用来标识它具体是Union中的哪一种类型(比如CustomString或CustomArray)。 - 对于
CustomString,你可以直接访问value字段;对于CustomArray,要使用你在查询中定义的别名aliasVar来访问数组值。 - 需要处理空值情况(比如你示例数据里那个没有
value的CustomArray),避免渲染出错。
修改后的React组件代码:
const ItemList = ({ data: { loading, error, allLinks } }) => { if (loading) { return <p>Loading ...</p>; } if (error) { return <p>{error.message}</p>; } // 渲染单个custom_attribute项的辅助函数 const renderCustomAttribute = (attr) => { switch (attr.__typename) { case 'CustomString': // 可根据需求格式化字符串,比如解析HTML内容 return <div className="custom-string">{attr.value}</div>; case 'CustomArray': // 先判断数组是否有值,避免空值报错 if (attr.aliasVar?.length) { return ( <ul className="custom-array"> {attr.aliasVar.map((item, idx) => ( <li key={idx}>{item}</li> ))} </ul> ); } return <div className="empty-array">No array values available</div>; default: return null; } }; return ( <div className="itemList"> {allLinks.items.map(item => ( <div key={item.id} className="item"> <h4>Item ID: {item.id}</h4> <div className="custom-attributes"> {item.custom_attributes.map((attr, idx) => ( <div key={idx} className="attribute-item"> {renderCustomAttribute(attr)} </div> ))} </div> </div> ))} </div> ); }; const channelsListQuery = gql` query ChannelsListQuery { allLinks { items { id custom_attributes { __typename ... on CustomString{ value } ... on CustomArray{ aliasVar: value } } } } } `;
额外说明:
- 我显式在查询中添加了
__typename(部分GraphQL客户端会自动返回,但显式请求更稳妥),确保能准确识别每个属性的类型。 - 用
renderCustomAttribute辅助函数拆分不同类型的渲染逻辑,让组件代码更清晰易维护。 - 针对
CustomArray使用可选链操作符?.处理空值,避免因字段不存在导致的运行时错误。 - 通过两层嵌套
map,分别遍历外层的items数组和内层的custom_attributes数组,完整渲染所有数据。
这样你就能正确访问Union类型的字段(包括别名后的aliasVar),并根据不同类型渲染对应的内容了。
内容的提问来源于stack exchange,提问作者Brunhilda
相关产品推荐
相关产品推荐

