React+GraphQL+react-pdf-renderer报错:无法读取undefined属性
排查方向及解决方案
1. 必须处理GraphQL查询的加载/错误状态
你的代码完全没考虑loading和error状态,当查询还在请求中时,data是undefined,直接访问data.getHotelDetailsByIds必然报错。先在组件里做判断:
if (loading) return <div>加载PDF中...</div>; if (error) return <div>加载失败:{error.message}</div>;
只有当数据就绪后,再调用renderContent。
2. 逐层校验数据结构,避免深层访问报错
不要直接写data.getHotelDetailsByIds.items[0],哪怕GraphQL直接查询有结果,前端接收时可能因为字段名拼写错误、嵌套结构缺失导致undefined。用可选链+空值合并做兜底:
const renderContent = () => { // 逐层校验,兜底空对象避免后续渲染报错 const hotelDetails = data?.getHotelDetailsByIds?.items?.[0] ?? {}; // 确认数据存在再渲染PDF内容 if (!hotelDetails.bookingConfirmationNumber) { return <div>无可用酒店数据</div>; } return ( <PDFViewer> <Document> <Page> <View> <Text>{hotelDetails.bookingConfirmationNumber}</Text> <Text>{hotelDetails.hotelName}</Text> <Text>{hotelDetails.address}</Text> <Text>{hotelDetails.hotelContactNumber}</Text> <Text>{hotelDetails.guestName}</Text> <Text>{hotelDetails.guests?.adults}</Text> <Text>{hotelDetails.guests?.children}</Text> </View> </Page> </Document> </PDFViewer> ) }
3. 确认react-pdf的渲染时机
react-pdf的渲染逻辑对数据变更的响应可能和普通组件不同,确保只有当hotelDetails有效时才渲染PDF组件。可以把renderContent改成条件渲染的一部分,而不是直接调用。
4. 检查查询变量是否正确传递
在组件里打印hotelBookingId和profile.userId,确认和你直接用GraphQL查询时的变量完全一致:
console.log('查询变量:', hotelBookingId, profile.userId);
如果变量传错(比如hotelBookingId是undefined或无效值),GraphQL会返回空数组,自然items[0]就是undefined。
5. 修正TypeScript类型断言问题
你直接用const hotelDetails: HotelDetailsType = ...做类型断言,但这不会改变实际值,只是欺骗编译器。如果实际值是undefined,断言后依然会报错。应该用类型守卫确保数据符合类型:
const isHotelDetails = (data: any): data is HotelDetailsType => { return !!data?.bookingConfirmationNumber && !!data?.hotelName; }; // 在renderContent里使用 const rawHotelDetails = data?.getHotelDetailsByIds?.items?.[0]; if (!isHotelDetails(rawHotelDetails)) { return <div>数据格式错误</div>; } const hotelDetails = rawHotelDetails;
内容的提问来源于stack exchange,提问作者Ced
相关产品推荐
相关产品推荐

