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

React钱包断开后自动重定向首页失败问题求助

问题解决思路

核心问题分析

  1. useNavigate报错原因:你把<Router>嵌套在了Navbar内部,导致useNavigate钩子无法获取到正确的Router上下文。Router必须包裹整个应用的根组件,才能让所有子组件共享路由上下文。
  2. 自动跳转逻辑缺失:之前的代码只在渲染时判断walletConnected状态返回跳转组件,但断开钱包的事件触发后,没有直接执行跳转操作,而是依赖组件重新渲染,这会导致跳转不及时或者失效。

具体修改步骤

1. 调整Router层级

把<Router>从NavbarMenu组件中移出,放到应用的最顶层(比如App.js),确保所有路由相关组件都在Router上下文内:

// App.js示例
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './Home';
import MyAccount from './MyAccount';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/myaccount" element={<MyAccount />} />
      </Routes>
    </Router>
  );
}

2. 修复NavbarMenu组件的跳转逻辑

  • 移除组件内部的<Router>标签
  • 在accountsChanged事件触发时直接调用navigate跳转
  • 替换废弃的Redirect为Navigate组件(react-router-dom v6语法)
  • 添加事件监听清理,防止内存泄漏

修改后的NavbarMenu代码:

import { Nav, Navbar, Container, Button } from 'react-bootstrap';
import { useNavigate, Navigate } from 'react-router-dom';
import { useState, useEffect } from 'react';

const NavbarMenu = ({ typeNavbar }) => {
  const [walletConnected, setWalletConnected] = useState(false);
  const navigate = useNavigate();    

  useEffect(() => {
    const handleAccountsChanged = async (accounts) => {
      if (!accounts.length) {
        setWalletConnected(false);
        // 断开钱包后直接跳转首页
        navigate("/");
      } else {
        setWalletConnected(true);
      }
    };

    // 监听钱包账户变化
    window.ethereum?.on("accountsChanged", handleAccountsChanged);

    // 组件卸载时移除监听
    return () => {
      window.ethereum?.removeListener("accountsChanged", handleAccountsChanged);
    };
  }, [navigate])

  const setFinalNavbar = () => {
    if (typeNavbar === "homepage") {
      return walletConnected 
        ? <Nav.Link href="/myaccount">My Account</Nav.Link>
        : <Button className={navbar_styles.connect_btn} variant="outline-success" onClick={connectWallet}>Connect Wallet</Button>;
    } else {
      return walletConnected 
        ? <Nav.Link href="/" className='text-success'>Back to home</Nav.Link>
        : <Navigate to="/" replace />;
    }
  }

  return (
    <Navbar sticky="top" bg="dark" variant="dark" expand="lg">
      <Container>
        <Navbar.Brand href="#home">
          <img
            src="/favicon.ico"
            width="30"
            height="30"
            className="d-inline-block align-top"
            alt="React Bootstrap logo"
          />{' '}
          Four-Leaf
        </Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="me-auto">
            {typeNavbar === "personal"
              ? <>
                <Nav.Link href="#home">Purchased numbers</Nav.Link>
                <Nav.Link href="#bet-number">Previous numbers</Nav.Link>
              </>
              : <>
                <Nav.Link href="#home">Home</Nav.Link>
                <Nav.Link href="#bet-number">Bet</Nav.Link>
                <Nav.Link href="#last-raffles">Last raffles</Nav.Link>
                <Nav.Link href="#link">Instructions</Nav.Link>
              </>
            }
            {setFinalNavbar()}
          </Nav>
        </Navbar.Collapse>
      </Container>
    </Navbar>
  )
}

export default NavbarMenu;

3. 注意事项

  • 确保你的react-router-dom版本是v6,v5和v6的路由语法差异很大,Redirect在v6中已被Navigate替代
  • 调用window.ethereum时加上可选链?.,防止用户未安装钱包时报错
  • 事件监听一定要在组件卸载时移除,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:55:15