React中使用Web3获取已连接钱包余额的问题
解决Metamask连接后无法获取钱包余额的问题
问题分析
你的代码存在几个关键问题导致无法正常获取余额:
web3.eth.getBalance是异步方法,未使用await,因此拿到的是Promise对象而非实际余额值- 直接导入的web3未与Metamask的provider绑定,需要通过
window.ethereum初始化有效实例 requestAccount中调用setWalletAddress后立刻console.log(walletAddress),由于useState是异步更新,此处打印的仍是旧值(不影响余额获取,但需注意)
方案一:修复Web3使用方式
修改getBalance函数,正确初始化web3并处理异步逻辑:
async function getBalance() { if (!window.ethereum || !walletAddress) return; // 绑定Metamask provider初始化web3实例 const web3Instance = new web3(window.ethereum); try { // 异步获取Wei单位余额 const balanceInWei = await web3Instance.eth.getBalance(walletAddress); // 转换为ETH格式 const balanceInEth = web3Instance.utils.fromWei(balanceInWei, 'ether'); console.log('钱包余额(ETH):', balanceInEth); } catch (error) { console.error('获取余额失败:', error); } }
方案二:使用已导入的Ethers.js(更推荐)
既然已引入ethers.js,用它实现会更简洁,无需同时维护web3和ethers:
import "./App.css"; import React, { useState } from "react"; import { ethers } from "ethers"; function App() { const [walletAddress, setWalletAddress] = useState(""); const [balance, setBalance] = useState("0"); // 新增余额状态 async function requestAccount() { console.log("Requesting account..."); if (!window.ethereum) { console.log("Metamask Wallet Absent"); return; } try { const accounts = await window.ethereum.request({ method: "eth_requestAccounts", }); setWalletAddress(accounts[0]); // 连接后自动获取余额 await getBalance(accounts[0]); } catch (error) { console.log("Error connecting Wallet"); } } async function getBalance(address) { const provider = new ethers.BrowserProvider(window.ethereum); try { const balance = await provider.getBalance(address); // 转换为ETH格式 const balanceInEth = ethers.formatEther(balance); setBalance(balanceInEth); console.log('钱包余额(ETH):', balanceInEth); } catch (error) { console.error('获取余额失败:', error); } } return ( <div className="App"> <header className="App-header"> <button onClick={requestAccount}>Connect Metamask Wallet</button> <h3>Wallet Address: {walletAddress}</h3> <h2>Account Balance: {balance} ETH</h2> <button onClick={() => getBalance(walletAddress)}>刷新余额</button> </header> </div> ); } export default App;
额外注意事项
- 调用余额获取函数前,先判断
walletAddress是否为空,避免无效请求 - 监听Metamask的
chainChanged事件,在用户切换网络时自动更新余额 - 始终添加异常捕获,处理用户拒绝授权、网络异常等情况
内容的提问来源于stack exchange,提问作者asfaa
相关产品推荐
相关产品推荐

