React+web3js如何设置加载屏直到链上交易确认完成
核心错误点
你当前的实现存在3个逻辑问题,达不到预期效果:
- 加载屏触发时机错误:
setLoadingScreen(1)放在交易哈希返回的回调里执行,用户点击按钮发起交易到拿到哈希的这段时间没有加载提示,应该在发起交易请求前就开启加载屏 - 异步方法未等待返回:
web3.eth.getTransactionReceipt是异步接口,你没有加await等待结果,同步调用拿到的只是pending状态的Promise对象,不是实际的交易回执 - 回执查询时机错误:刚拿到交易哈希时,交易仅被节点广播到内存池等待矿工打包,并未完成上链确认,此时立刻查询回执大概率返回
null,会导致加载屏在交易未上链时就提前关闭
正确实现方式
不用自己手写轮询查询回执,web3.js的合约send()方法已经封装好了全流程的事件监听,直接用是最稳妥的:
// 点击按钮发起交易的第一时间就开启加载屏 setLoadingScreen(1); try { const txResult = await TokenContract.methods.buy().send({ from: account, value: web3.utils.toWei(inputBuyQty, 'ether') }) .on('transactionHash', (txHash) => { // 仅代表节点接收并广播了交易,交易还在内存池等待打包,不要在这里关加载 console.log('交易已广播,哈希值:', txHash); }) .on('receipt', (txReceipt) => { // 交易已经被打包进区块,完成链上确认,此时关闭加载屏 console.log('交易上链确认成功,回执:', txReceipt); setLoadingScreen(0); // 此处可添加交易成功的业务逻辑,比如提示、刷新余额等 }) .on('error', (error) => { // 交易打包失败、gas不足、被合约revert都会触发这个事件 console.error('交易失败:', error); setLoadingScreen(0); // 此处可添加交易失败的提示逻辑 }); } catch (error) { // 捕获用户拒绝钱包签名、网络断开这类前置异常 console.error('交易发起异常:', error); setLoadingScreen(0); }
注意事项
- 不要在
transactionHash事件触发时关闭加载屏,这个节点交易还没上链,随时可能因为gas不足、合约校验失败等原因被丢弃 - 所有异常分支都必须加
setLoadingScreen(0)逻辑,避免页面一直卡在加载状态 - 如果需要等多个区块确认再判定交易最终成功,可以额外配置
confirmation事件监听,在确认数达到你要求的阈值时再关闭加载屏
内容的提问来源于stack exchange,提问作者Haji Solihin
相关产品推荐
相关产品推荐

