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

组合web3UIkit+React/Moralis时出现MaxListeners Exceeded问题求助

问题:多次切换页面后触发MaxListeners Exceeded报错

我在项目中反复遇到MaxListeners Exceeded问题,多次点击导航栏切换页面后,控制台就会弹出该报错。代码无特殊逻辑,但始终找不到根因。

为排查问题,我制作了一个仅保留必要依赖的极简项目,怀疑是web3UIkit、React、Moralis和/或Next之间存在兼容问题,但无法确认。现请求帮忙找出问题原因,或提供彻底解决的方案。


相关代码文件

_app.js

import { MoralisProvider } from "react-moralis";
import "../styles/globals.css";

function MyApp({ Component, pageProps }) {
  return (
    <MoralisProvider initializeOnMount={false}>
      <Component {...pageProps} />
    </MoralisProvider>
  );
}

export default MyApp;

Index.js

import Head from "next/head";
import Header from "../components/Header";
import Navbar from "../components/Navbar";
import styles from "../styles/Home.module.css";

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <Header></Header>
      <Navbar></Navbar>
      <div>This page is an example to illustrate the maxlisteners issue</div>
    </div>
  );
}

Page1.js

import Head from "next/head";
import Header from "../components/Header";
import Navbar from "../components/Navbar";
import styles from "../styles/Home.module.css";

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <Header></Header>
      <Navbar></Navbar>
      <div>
        Page 1: This page is an example to illustrate the maxlisteners issue
      </div>
    </div>
  );
}

Header.js(组件)

import { ConnectButton } from "@web3uikit/web3";

export default function Header() {
  return (
    <div className="p-5 border-b-2 flex flex-row bg-slate-400">
      <h1 className="py-4 px-4 font-blog text-3xl">Maxlisteners Example</h1>
      <div className="ml-auto py-2 px-4">
        <ConnectButton moralisAuth={false}></ConnectButton>
      </div>
    </div>
  );
}
import Link from "next/link";

export default function Navbar() {
  return (
    <div className="bg-slate-400">
      <ul className="grid grid-cols-3 place-items-center py-2 border-b-2 f">
        <li>
          <Link href="/">
            <a>Home</a>
          </Link>
        </li>
        <li>
          <Link href="/page1">
            <a>Page1</a>
          </Link>
        </li>
      </ul>
    </div>
  );
}

package.json

{
  "name": "maxlisteners",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@web3uikit/core": "^0.1.5",
    "@web3uikit/icons": "^0.1.5",
    "@web3uikit/web3": "^0.1.5",
    "magic-sdk": "^9.0.0",
    "moralis": "^2.0.3",
    "next": "12.2.5",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-moralis": "^1.4.1"
  },
  "devDependencies": {
    "eslint": "8.22.0",
    "eslint-config-next": "12.2.5"
  }
}

问题原因与解决方案

根因分析

核心问题是**@web3uikit/web3的ConnectButton组件在页面切换时未正确清除事件监听器**:每次页面挂载都会新增监听器,而页面卸载时这些监听器未被清理,累积超过Node.js默认的最大监听器数量(默认10个)后触发报错。

解决方法

1. 升级依赖版本(推荐)

@web3uikit早期版本(如你使用的0.1.5)存在内存泄漏问题,升级到最新稳定版可修复。执行命令:

npm update @web3uikit/core @web3uikit/icons @web3uikit/web3

2. 全局提升ConnectButton

将Header组件(包含ConnectButton)放到_app.js中作为全局组件,避免每次页面切换重复挂载:
修改_app.js:

import { MoralisProvider } from "react-moralis";
import "../styles/globals.css";
import Header from "../components/Header";

function MyApp({ Component, pageProps }) {
  return (
    <MoralisProvider initializeOnMount={false}>
      <Header />
      <Component {...pageProps} />
    </MoralisProvider>
  );
}

export default MyApp;

同时移除Index.js和Page1.js中的<Header></Header>引用,让Header仅挂载一次。

3. 手动清理监听器(临时方案)

若暂时无法升级依赖,可在Header组件中通过useEffect手动清理事件监听器:
修改Header.js:

import { ConnectButton } from "@web3uikit/web3";
import { useEffect } from "react";

export default function Header() {
  useEffect(() => {
    return () => {
      const emitter = window.ethereum?.provider;
      if (emitter?.removeAllListeners) {
        emitter.removeAllListeners("accountsChanged");
        emitter.removeAllListeners("chainChanged");
      }
    };
  }, []);

  return (
    <div className="p-5 border-b-2 flex flex-row bg-slate-400">
      <h1 className="py-4 px-4 font-blog text-3xl">Maxlisteners Example</h1>
      <div className="ml-auto py-2 px-4">
        <ConnectButton moralisAuth={false}></ConnectButton>
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:33:44