通过web3.js连接Metamask到React应用时报错,求排查解决方法
错误修复方案
错误1:TypeError: Cannot read properties of null (reading 'eth')
原因
useWeb3内部通过useEffect初始化web3实例,属于副作用异步执行,组件首次渲染时web3的初始值还是null,此时直接在组件顶层调用setUserAccount()会读取null的eth属性报错- 废弃API使用:
window.ethereum.enable()已经被官方弃用,应改用eth_requestAccounts标准方法
修复方案(修改App.js)
把顶层调用setUserAccount()的逻辑改成依赖web3的useEffect,同时替换废弃API:
// App.js 顶部新增导入useEffect import {useEffect} from 'react' function App() { const {address,balance,message, setBalance,setAddress} = useStoreApi(); const web3 = useWeb3(); const setUserAccount = async () => { console.log("获取账户"); // 先判断web3存在再执行后续逻辑 if(!window.ethereum || !web3) return; try { const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); setAddress(accounts[0]); } catch (error) { console.error("钱包连接失败:", error) } }; // 等web3初始化完成后再执行连接逻辑 useEffect(() => { setUserAccount() }, [web3]) // 后续return渲染部分保持原有代码不变 }
错误2:Unknown type of action ${action.type}
原因
- action.type大小写不匹配:reducer中定义的触发条件是全大写
"NEW-ADDRESS",但storeApi.js中dispatch的是大小写混合的"New-Address",匹配失败进入default分支抛错 - 模板字符串语法错误:reducer中报错的字符串使用了单引号包裹,无法解析
${action.type}变量,需要改用反引号 - 未定义
SET-BALANCE的处理逻辑:storeApi.js中存在setBalance方法触发"SET-BALANCE"类型的action,但reducer中没有对应case处理
修复方案
第一步:修改store.js的reducer逻辑
const reducer = (state, action) => { switch(action.type){ case "NEW-ADDRESS": return { ...state, address: action.newAddress, message: action.message } // 新增SET-BALANCE的处理逻辑 case "SET-BALANCE": return { ...state, balance: action.newBalance } default: // 单引号改反引号,支持模板变量解析 throw new Error(`Unknown type of action ${action.type}`); } };
第二步:修改storeApi.js的action.type
setAddress: newAddress => { dispatch({ // 改成全大写和reducer定义保持一致 type: "NEW-ADDRESS", newAddress, message: "New account added successfully!" }); }
错误3:StoreProvider组件报错
原因
是错误2抛出的异常没有被捕获导致的上层组件报错,错误2修复后该问题会自动消失。
可选优化
getWeb3.js中本地节点连接的代码拼写错误,Web3.provider.HttpProvider需要改为复数形式Web3.providers.HttpProvider,避免本地节点连接时报错。
内容的提问来源于stack exchange,提问作者Zuffido
相关产品推荐
相关产品推荐

