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

Web3Modal WalletConnect切换页面时连接状态丢失问题求助

Web3Button路由跳转后状态不同步问题修复方案

问题分析

该问题源于Next.js客户端路由跳转时,Wagmi的钱包连接状态未自动同步,加上组件 hydration 逻辑与状态监听不完整,导致Web3Button无法感知钱包实际连接状态,出现连接后仍显示"Connect Wallet"、重复连接报错的情况。

修复方案

1. 优化Wagmi客户端初始化与路由监听

修改_app.js,添加路由切换监听,确保路由跳转后重新触发Wagmi连接检查,并将Web3Modal移至WagmiConfig上下文内:

import "../styles/globals.css";
import { ThemeProvider } from "next-themes";
import Layout from "../components/layout";
import { Provider } from "react-redux";
import { store } from "../redux/store";
import { Web3Modal } from "@web3modal/react";
import Meta from "../components/Meta";
import UserContext from "../components/UserContext";
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/router";
import {
  EthereumClient,
  w3mConnectors,
  w3mProvider,
} from "@web3modal/ethereum";
import { configureChains, createClient, WagmiConfig } from "wagmi";
import { arbitrum } from "wagmi/chains";

function MyApp({ Component, pageProps }) {
  const [ready, setReady] = useState(false);
  const scrollRef = useRef({
    scrollPos: 0,
  });
  const router = useRouter();
  const chains = [arbitrum];
  const projectId = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
  const { provider } = configureChains(chains, [w3mProvider({ projectId })]);
  const wagmiClient = createClient({
    autoConnect: true,
    connectors: w3mConnectors({ projectId, version: 2, chains }),
    provider,
  });
  const ethereumClient = new EthereumClient(wagmiClient, chains);

  useEffect(() => {
    // 路由切换时重新触发连接检查
    const handleRouteChange = () => {
      wagmiClient.connect({ connector: wagmiClient.connectors[0], reconnect: true });
    };

    router.events.on('routeChangeComplete', handleRouteChange);
    setReady(true);

    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router, wagmiClient]);

  return (
    <>
      {ready ? (
        <WagmiConfig client={wagmiClient}>
          <Provider store={store}>
            <ThemeProvider enableSystem={true} attribute="class">
              <UserContext.Provider value={{ scrollRef: scrollRef }}>
                <Layout>
                  <Component {...pageProps} />
                </Layout>
              </UserContext.Provider>
            </ThemeProvider>
          </Provider>
          {/* 将Web3Modal移入WagmiConfig上下文,确保状态同步 */}
          <Web3Modal
            themeVariables={{
              "--w3m-accent-color": "#8358FF",
              "--w3m-background-color": "#131740",
            }}
            projectId={projectId}
            ethereumClient={ethereumClient}
          />
        </WagmiConfig>
      ) : null}
    </>
  );
}

2. 强化Header组件的状态监听

修改Header组件,添加路由切换时的手动状态检查,确保组件能及时响应连接状态变化:

import Image from "next/image";
import Link from "next/link";
import DarkMode from "../mode/DarkMode";
import Logo from "./../../public/images/logo.png";
import WhiteLogo from "./../../public/images/logo_white.png";
import { v4 as uuidv4 } from "uuid";
import { useRouter } from "next/router";
import {
  isChildrenPageActive,
  isParentPageActive,
} from "../../utils/daynamicNavigation";
import { useEffect, useState } from "react";
import { useAccount, useEnsName, useConnect } from "wagmi";
import { Web3Button } from "@web3modal/react";
import DropDownInfos from "./fragments/DropDownInfos";

export default function Header() {
  const { address, isConnected, isConnecting } = useAccount();
  const { data: ensName } = useEnsName({ address });
  const { connect } = useConnect();
  const [toggle, setToggle] = useState(false);
  const [isCollapse, setCollapse] = useState(null);
  const [hydrated, setHydrated] = useState(false);
  const router = useRouter();

  useEffect(() => {
    setHydrated(true);
    // 窗口resize处理
    const handleResize = () => {
      if (window.innerWidth >= 1024) {
        setToggle(false);
      }
    };
    window.addEventListener("resize", handleResize);

    // 路由切换时手动检查钱包状态
    const handleRouteChange = () => {
      if (typeof window !== "undefined" && window.ethereum) {
        window.ethereum.request({ method: 'eth_accounts' }).then(accounts => {
          if (accounts.length > 0 && !isConnected) {
            connect({ connector: window.ethereum });
          }
        });
      }
    };
    router.events.on('routeChangeComplete', handleRouteChange);

    return () => {
      window.removeEventListener("resize", handleResize);
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router, isConnected, connect]);

/* Some code */

            <div className="ml-8 hidden items-center lg:flex xl:ml-12">
              {/* 根据连接状态动态显示按钮文本 */}
              <Web3Button 
                label={isConnected ? "Disconnect" : "Connect"} 
                icon="show"
                disabled={isConnecting}
              />

关键修复点说明

  • 将Web3Modal移入WagmiConfig内部,确保组件能正确获取Wagmi上下文状态
  • 路由切换时触发Wagmi重新连接检查,强制同步账户状态
  • 在Header组件中添加路由监听,手动检查钱包账户,弥补自动同步的不足
  • 以isConnected、isConnecting作为依赖项,确保组件在状态变化时及时重渲染

额外建议

  • 升级Wagmi与Web3Modal至最新版本,避免旧版本的路由同步bug
  • 确保WagmiConfig在hydration完成后再渲染,避免状态初始化异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:17:19