You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useState无法更新currentAccount,Metamask场景下方案失效

问题分析与修复方案

核心问题点

  1. useEffect依赖引发重复执行与事件重复绑定
    你的useEffect依赖了walletConnected和currentAccount,每次这两个状态更新都会重新触发useEffect并调用onPageLoad,导致accountsChanged事件被多次绑定,引发状态更新混乱。同时setCurrentAccount是异步操作,在connectWallet后立即调用getUserRole,大概率拿到的还是旧的currentAccount值。

  2. 事件监听器未做清理
    组件卸载时没有移除accountsChanged的监听器,容易造成内存泄漏或不必要的重复触发。

修复步骤

1. 调整初始化逻辑,避免重复执行

将初始化改为仅在组件挂载时执行一次,同时添加事件监听器的清理逻辑:

useEffect(() => {
  const initWallet = async () => {
    if (!walletConnected) {
      await connectWallet();
      
      // 定义账户变化处理函数
      const handleAccountsChanged = (accounts) => {
        setCurrentAccount(accounts[0]);
      };
      
      // 绑定事件监听器
      window.ethereum.on('accountsChanged', handleAccountsChanged);
      
      // 组件卸载时移除监听器,防止内存泄漏
      return () => {
        window.ethereum.removeListener('accountsChanged', handleAccountsChanged);
      };
    }
  };

  initWallet();
}, [walletConnected]); // 仅当walletConnected状态变化时触发,或用空数组仅在组件挂载时执行

2. 分离getUserRole调用逻辑

让getUserRole自动响应currentAccount变化,无需手动在多个地方调用:

useEffect(() => {
  // 仅当currentAccount存在时调用
  if (currentAccount) {
    getUserRole();
  }
}, [currentAccount]); // 依赖currentAccount,状态更新时自动执行

3. 优化connectWallet函数(可选)

添加日志确认账户获取状态,确保accounts数组有效:

const connectWallet = async () => {
  try {
    const provider = await getProviderOrSigner();
    const accounts = await provider.send("eth_requestAccounts", []);
    
    // 检查账户是否获取成功
    if (!accounts || accounts.length === 0) {
      console.error("未获取到有效账户");
      return;
    }
    
    setCurrentAccount(accounts[0]);
    setWalletConnected(true);
    return provider;
  } catch (error) {
    console.error("连接钱包失败:", error);
  }
};

4. 移除冗余的onPageLoad调用

将原onPageLoad中的逻辑整合到上述initWallet函数中,避免重复执行带来的问题。

额外检查点

  • 确认getProviderOrSigner函数能正确返回MetaMask的provider,无异常。
  • 检查组件中currentAccount的初始值是否为'',保证状态更新逻辑正常。

内容的提问来源于stack exchange,提问作者asusrid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:31:34