React-TypeScript-Ant Design双API调用及数据关联错误求助
问题解决:React-TypeScript+AntD中"cannot find name data"错误及接口数据关联
错误原因
代码里直接使用了未定义的data变量,但组件中实际维护的是两个状态:customersData(客户信息)和shipmentData(运单数据),同时还有first_name、email等未声明的变量,这是导致报错的核心原因。
分步解决
1. 修复"cannot find name data"错误
- 将JSX中所有
data替换为对应的状态变量:客户信息区域用customersData,表格数据源用shipmentData - 为状态变量添加TypeScript类型声明,避免
null导致的类型报错 - 使用可选链
?.或条件判断确保数据存在后再渲染,防止空值访问
2. 关联客户与运单数据
表格的运单行需要显示客户头像,这里采用合并数据的方式:在获取运单数据后,将客户的头像字段追加到每个运单对象中,确保表格列的render函数能直接访问到该字段。
修正后的完整代码
import React, { useState, useEffect } from 'react'; import { Table, Space, Link } from 'antd'; import { ColumnsType } from 'antd/es/table'; interface SingleCustomerShipmentData { _id: string; shipping_type: string; origin_port_city: string; destination_port_city: string; shipment_pickup_date: string; } interface SingleCustomerData { id: string; first_name: string; last_name: string; email: string; phone: string; Avatar: string; } // 调整columns泛型,允许访问合并后的Avatar字段 const columns: ColumnsType<SingleCustomerShipmentData & Pick<SingleCustomerData, 'Avatar'>> = [ { title: 'Shipment Type', dataIndex: 'shipping_type', key: 'shipping_type', render: (shipping_type, record) => { return ( <div> <img className='customers-avatar' src={record.Avatar} alt="" /> {shipping_type} </div> ) }, }, { title: 'Origin', dataIndex: 'origin_port_city', key: 'origin_port_city', }, { title: 'Destination', dataIndex: 'destination_port_city', key: 'destination_port_city', }, { title: 'Shipment Date', dataIndex: 'shipment_pickup_date', key: 'shipment_pickup_date', }, { title: 'Shipping ID', dataIndex: '_id', key: '_id', }, { title: '', key: 'action', render: () => { return ( <Space size="middle"> <Link to="/shipment-details" className='space-action-green'>View Details</Link> </Space> ) }, }, ]; const Shipments: React.FC = () => { // 为状态添加明确的TS类型声明 const [shipmentData, setShipmentData] = useState<(SingleCustomerShipmentData & Pick<SingleCustomerData, 'Avatar'>)[] | undefined>(); const [customersData, setCustomersData] = useState<SingleCustomerData | undefined>(); const [loading, setLoading] = useState(false); // 合并API请求到同一个useEffect,减少冗余渲染 useEffect(() => { getSingleCustomer(); getSingleCustomerShipment(); }, []); const getSingleCustomer = () => { setLoading(true); return makeAPICall({ path: `get_single_customer/123456789`, method: "GET", }) .then((data) => { setCustomersData(data as SingleCustomerData); setLoading(false); console.log(data); }) .catch((err) => { setLoading(false); console.log(err); }); } const getSingleCustomerShipment = () => { setLoading(true); return makeAPICall({ path: `get_single_customer_shipments/123456789`, method: "GET" }).then((data) => { // 合并客户头像到每个运单数据中 const mergedData = (data as SingleCustomerShipmentData[]).map(item => ({ ...item, Avatar: customersData?.Avatar || '' })); setShipmentData(mergedData); setLoading(false); console.log(data); }).catch((err) => { setLoading(false); console.log(err); }) } return ( <SiderLayout> <div className="site-layout-background" style={{ padding: "40px 40px", minHeight: 710 }}> <Link className='shipment-back' to="/"> <img src={ArrowLeft} alt="" /> </Link> {loading ? "loading..." : ( <> {/* 客户信息区域:使用customersData并添加可选链防止空值报错 */} <div className='shipment__container'> <div className='shipment__container--image'> <img src={customersData?.Avatar} alt="" style={{ marginRight: 10 }} /> <div> <p className='bold'>{customersData?.first_name}</p> <p>{customersData?.email}</p> <p>{customersData?.phone}</p> </div> </div> <div> <span className='shipment__container--edit'>Edit</span> </div> </div> <div className='shipment__border'> <div className='shipment-spacing'> <button className='new-shipment'>Add New Shipment {" "} +</button> <select className='shipment-select' name="" id=""> <option value="">Shipment Type</option> </select> <select className='shipment-select' name="" id=""> <option value="">Shipment Date</option> </select> </div> <div className='shipment-search'> <form className="nosubmit"> <input className="nosubmit" type="search" placeholder="Search by shipment ID, Destination" /> </form> </div> </div> {/* 表格使用合并后的运单数据,添加rowKey符合AntD要求 */} <Table columns={columns} dataSource={shipmentData} rowKey="_id" /> </> )} </div> </SiderLayout> );
关键修改点说明
- 给
useState添加明确的TypeScript类型,避免类型推断错误 - 将两个API请求合并到同一个
useEffect,减少组件不必要的渲染 - 在获取运单数据后,把客户的
Avatar字段合并到每个运单对象中,确保表格render能访问到头像 - 所有数据访问添加可选链
?.,防止数据未加载时的空值报错 - 修复
Space组件的语法错误(原代码缺少闭合标签) - 给Table添加
rowKey属性,符合AntD Table的规范要求
内容的提问来源于stack exchange,提问作者lakaJS
相关产品推荐
相关产品推荐

