在React的map函数中使用API Action:通过ID获取名称的咨询
在React Map函数中调用API Action获取名称的正确做法
嘿,我来帮你梳理下这个问题——你现在直接在map里调用this.props.getJewelleryName(wit.itemId)的写法会踩几个坑:首先,每次组件渲染都会触发API请求,很容易造成无限渲染循环;其次,API请求是异步的,渲染的时候数据还没返回,根本没法展示你要的名称;最后,批量触发单个请求也会浪费网络资源。
下面给你几个靠谱的解决方案,你可以根据后端接口情况选:
方案一:批量获取所有名称(最优选择)
如果后端支持批量查询接口,先把所有需要的itemId提取出来,一次性请求所有名称,存在Redux Store或者组件State里,之后渲染的时候直接从存储的映射表中取值就行。
举个类组件的例子:
componentDidMount() { // 从invoiceItem数组里提取所有itemId const itemIds = this.props.getInvoiceInfo.invoiceItem.map(wit => wit.itemId); // 调用批量获取名称的Action(需要后端支持批量接口) this.props.getJewelleryNames(itemIds) .then(() => { // 标记数据已加载完成 this.setState({ isLoaded: true }); }); } render() { // 假设Redux Store里存了一个{itemId: 对应名称}的映射对象 const { jewelleryNameMap } = this.props; const { isLoaded } = this.state; if (!isLoaded) { return <div>加载中...</div>; } return ( <div> {this.props.getInvoiceInfo.invoiceItem.map((wit, index) => ( <div key={index}> 商品ID:{wit.itemId} | 商品名称:{jewelleryNameMap[wit.itemId] || '未知'} </div> ))} </div> ); }
方案二:封装成独立组件处理单个请求
如果后端不支持批量查询,那就把每个条目封装成单独的组件,让每个组件自己处理API请求,这样既能避免父组件的重复渲染问题,也能让每个条目只请求自己需要的数据。
示例代码:
// 单个珠宝条目组件 class JewelleryItem extends React.Component { state = { name: '加载中...' }; componentDidMount() { // 组件挂载时请求对应ID的名称 this.props.getJewelleryName(this.props.itemId) .then(response => { this.setState({ name: response.data.jewelleryName }); }) .catch(() => { this.setState({ name: '获取名称失败' }); }); } render() { return <div>{this.props.itemId} - {this.state.name}</div>; } } // 父组件的render方法 render() { return ( <div> {this.props.getInvoiceInfo.invoiceItem.map((wit, index) => ( <JewelleryItem key={index} itemId={wit.itemId} getJewelleryName={this.props.getJewelleryName} /> ))} </div> ); }
为啥不能直接在render里调用Action?
再跟你强调下原因,避免以后踩同样的坑:
- 无限渲染循环:Action触发后会更新State/Store,State变化又会触发组件重新render,render里又调用Action,循环往复停不下来
- 异步数据无法即时展示:API请求是异步操作,render执行的时候请求还没完成,根本拿不到返回的名称
- 性能浪费:每次render都发起新的请求,大量重复请求会拖慢页面加载速度,还会增加后端压力
内容的提问来源于stack exchange,提问作者Chandra Prakash




