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

React Router路由到指定页面时函数被多次调用问题求解(Web3 DApp场景)

问题原因

你遇到的checkChainID多次调用问题是React组件副作用处理不当导致的,核心问题有3个:

  1. 你直接把window.ethereum事件绑定、checkChainID()调用写在了MintPage组件的顶层,组件每渲染一次这些代码就会执行一遍:不仅会反复新增重复的事件监听器,还会每次都触发checkChainID执行。
  2. checkChainID会触发loadBlockchainData,后者内部调用了setCurrentAccount、setCurrentBalance两个状态更新方法,每次状态更新都会触发组件重新渲染,渲染又执行顶层的checkChainID,形成无限循环,调用次数自然会异常升高。
  3. 你在入口处启用了React.StrictMode,开发环境下它会故意让组件重复渲染两次来排查不合理的副作用,也会让你观测到的调用次数翻倍。

修复方案

使用React的useEffect钩子处理所有副作用逻辑,确保事件绑定、初始校验只在组件第一次挂载时执行一次,同时组件卸载时移除监听器,避免残留的监听触发逻辑。

关键修改代码(MintPage.js)

首先新增导入useEffect:

import React, { useState, useEffect } from 'react';

然后删除MintPage组件顶层原来的3行逻辑:

// 删掉下面这三行
window.ethereum.on('chainChanged', (_chainId) => checkChainID());
window.ethereum.on('accountsChanged', (_accounts) => loadBlockchainData());
checkChainID();

替换成下面的useEffect代码:

useEffect(() => {
  // 声明事件回调函数
  const handleChainChange = (_chainId) => checkChainID();
  const handleAccountChange = (_accounts) => loadBlockchainData();

  // 绑定钱包事件监听
  window.ethereum.on('chainChanged', handleChainChange);
  window.ethereum.on('accountsChanged', handleAccountChange);

  // 组件挂载时仅执行一次初始链ID校验
  checkChainID();

  // 清理函数:组件卸载时移除事件监听,防止内存泄漏和残留触发
  return () => {
    window.ethereum.removeListener('chainChanged', handleChainChange);
    window.ethereum.removeListener('accountsChanged', handleAccountChange);
  }
}, []); // 空依赖数组保证逻辑仅在组件挂载、卸载时执行

附加优化建议

你入口index.js里的window.ethereum.enable()是已经废弃的API,建议替换为符合当前钱包规范的写法:

// 替换原来的 window.ethereum.enable()
window.ethereum.request({method: 'eth_requestAccounts'})

另外你观测到主动导航到同一路由时函数被调用2次的情况,是开发环境下React.StrictMode的默认行为,生产环境构建后会自动变成只调用1次,不需要额外处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:18:03