React JS连接MetaMask按钮异常及ETH余额格式化问题求助
React连接MetaMask问题修复及余额格式化方案
一、ESLint警告解决
你收到的ESLint警告都是因为变量或函数定义后从未使用:
errorMessage:定义了状态但未在页面展示错误提示defaultAccount:存储了连接的账户地址但未渲染userBalance:余额状态未在页面显示getUserBalance:定义了获取余额的函数但从未调用
解决方法是在JSX中添加这些内容的展示,并在合适时机调用函数。
二、连接功能修复
代码连接失败主要有两个问题:
按钮点击事件错误:
原代码中onClick={() => connectWallet}仅传递了函数引用,未执行函数。需改为:<button className="btn btn-secondary btn-md" onClick={connectWallet}> 连接MetaMask</button>同时注意按钮样式类要放在
className属性中,原写法直接写btn btn-secondary btn-md无效。账户切换时未正确获取余额:
accountChanged函数错误地将账户地址赋值给userBalance,应改为调用getUserBalance获取实际余额:const accountChanged = (newAccount) => { setDefaultAccount(newAccount); getUserBalance(newAccount); };
三、余额格式化为ETH单位
MetaMask的eth_getBalance接口返回十六进制格式的Wei(以太坊最小单位),1 ETH = 10^18 Wei,需转换为ETH:
添加格式化函数:
const formatWeiToEth = (wei) => { if (!wei) return '0.0000'; // 十六进制转十进制后除以1e18,保留4位小数 return (parseInt(wei, 16) / 1e18).toFixed(4); };
四、完整修复后的代码
import React, { useState } from "react"; import "./App.css"; // 补充CSS文件后缀 import Navbar from "./Navbar"; const Metamask = () => { const [errorMessage, setErrorMessage] = useState(null); const [defaultAccount, setDefaultAccount] = useState(null); const [userBalance, setUserBalance] = useState(null); const connectWallet = () => { if (window.ethereum) { window.ethereum.request({ method: 'eth_requestAccounts' }) .then(result => { accountChanged(result[0]); }) .catch(err => { setErrorMessage(err.message); // 捕获请求错误 }); } else { setErrorMessage("请安装MetaMask钱包"); } }; const accountChanged = (newAccount) => { setDefaultAccount(newAccount); getUserBalance(newAccount); setErrorMessage(null); // 切换账户时清空错误提示 }; const getUserBalance = (address) => { window.ethereum.request({ method: 'eth_getBalance', params: [address, 'latest'] }) .then(balance => { setUserBalance(balance); }) .catch(err => { setErrorMessage("获取余额失败"); }); }; const formatWeiToEth = (wei) => { if (!wei) return '0.0000'; return (parseInt(wei, 16) / 1e18).toFixed(4); }; return ( <div className="metamask"> <Navbar /> <h1>MetaMask钱包连接</h1> {/* 显示错误信息 */} {errorMessage && <p style={{ color: 'red' }}>{errorMessage}</p>} {/* 显示已连接的账户和余额 */} {defaultAccount && ( <div> <p>当前账户: {defaultAccount}</p> <p>账户余额: {formatWeiToEth(userBalance)} ETH</p> </div> )} {/* 未连接时显示连接按钮 */} {!defaultAccount && ( <button className="btn btn-secondary btn-md" onClick={connectWallet}> 连接MetaMask </button> )} </div> ); }; export default Metamask;
内容的提问来源于stack exchange,提问作者Gustavo Payano
相关产品推荐
相关产品推荐

