React操作MySQL插入主记录后读取ID失败,可否通过then调整执行顺序
问题根源
你的代码问题出在异步逻辑没有按顺序等待执行,两个核心错误:
- 主记录创建方法
SiteReportCardMasterService.createSiteReportCardMaster是返回Promise的异步方法,你没有等待它执行完成就触发了后续的查询主记录、插入明细逻辑,此时新增的主记录还没入库,自然查不到对应rid setState本身也是异步更新方法,调用后立即读取this.state拿到的还是更新前的旧值,也会导致取值失败
解决方案
把异步逻辑改成按顺序等待执行,用async/await语法改写后逻辑更清晰,修改后代码如下:
copyReportCard = async (e) => { e.preventDefault(); try { const X = parseInt(this.state.selectedreportcardmasterid, 10) // 1. 获取原始报表主记录 const masterRes = await ReportCardMasterService.getReportCardMasterById(X) const reportcardmaster = masterRes.data; // 2. 组装新站点主记录 const sitereportcardmaster = { sitereportcardmasterCode: this.state.rCode, sitereportcardmasterName: reportcardmaster.reportcardmasterName, sitereportcardmastergradeLimit: reportcardmaster.reportcardmastergradeLimit, sitereportcardmasterColora: reportcardmaster.reportcardmasterColora, sitereportcardmasterColorb: reportcardmaster.reportcardmasterColorb, sitereportcardmasterColorc: reportcardmaster.reportcardmasterColorc, sitereportcardmasterColord: reportcardmaster.reportcardmasterColord, sitereportcardmasterColore: reportcardmaster.reportcardmasterColore, sitereportcardmastercpymasterId: reportcardmaster.reportcardmastercpymasterId, sitereportcardmasterComments: '', sitereportcardmasterCategorytotal: '', sitemaster_sitemasterId:this.props.match.params.sitemaster_sitemasterid }; // 3. 等待主记录创建完成,这里如果接口支持直接返回新增记录ID/对象,可以直接取结果不用后续全量查询 await SiteReportCardMasterService.createSiteReportCardMaster(sitereportcardmaster); // 4. 查询所有站点主记录 const siteMasterRes = await SiteReportCardMasterService.getSiteReportCardMaster() const siteMasterList = siteMasterRes.data let rid = null // 直接用返回的列表找rid,不用依赖setState的异步更新 for (let i = 0; i < siteMasterList.length; i++) { if (siteMasterList[i].sitereportcardmasterCode === this.state.rCode){ rid = siteMasterList[i].sitereportcardmasterid break } } if (!rid) throw new Error('未找到新增的主记录ID') // 把rid存到state this.setState({rid, sitereportcardmaster: siteMasterList}) // 5. 查询原始报表明细 const detailRes = await ReportCardDetailsService.getReportCardDetails() const detailList = detailRes.data this.setState({reportcarddetails: detailList}) // 6. 批量插入明细 for (let i = 0; i < detailList.length; i++) { if (detailList[i].reportcardmaster_reportcardmasterId === X) { const sitereportcarddetails = { sitereportcarddetailsSequence: detailList[i].reportcarddetailsSequence, sitereportcarddetailsDescription: detailList[i].reportcarddetailsDescription, sitereportcarddetailsCriteria: detailList[i].reportcarddetailsCriteria, sitereportcarddetailsWeight: detailList[i].reportcarddetailsWeight, sitereportcarddetailsScore: detailList[i].reportcarddetailsScore, sitereportcarddetailsWeightedscore: detailList[i].reportcarddetailsWeightedscore, sitereportcarddetailsColor: detailList[i].reportcarddetailsColor, sitereportcarddetailsComment: detailList[i].reportcarddetailsComment, reportcarddetailcategory_reportcarddetailcategoryId: detailList[i].reportcarddetailcategory_reportcarddetailcategoryId, sitereportcardmaster_sitereportcardmasterId: rid } await SiteReportCardDetailsService.createSiteReportCardDetails(sitereportcarddetails); } } } catch (err) { // 按需添加错误处理逻辑 console.error('复制报表失败:', err) } }
优化建议
如果后端的createSiteReportCardMaster接口可以直接返回插入成功的主记录完整数据/ID,就可以省略全量查询主记录的步骤,不仅减少一次接口调用,还能避免同一时间多用户插入相同rCode导致的匹配错误。
内容的提问来源于stack exchange,提问作者HighwayRob
相关产品推荐
相关产品推荐

