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

React项目中useNavigate()报错:需在<Router>上下文使用的问题求助

React路由错误:useNavigate() 只能在组件上下文使用

报错信息

Uncaught runtime errors:
×
ERROR
useNavigate() may be used only in the context of a <Router> component.
    at invariant (http://localhost:3000/static/js/bundle.js:1123:11)
    at useNavigateUnstable (http://localhost:3000/static/js/bundle.js:66522:102)
    at useNavigate (http://localhost:3000/static/js/bundle.js:66519:46)
    at App (http://localhost:3000/static/js/bundle.js:83:81)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:26618:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:29904:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:31200:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:16210:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:16254:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:16311:35)
ERROR
useNavigate() may be used only in the context of a <Router> component.
    at invariant (http://localhost:3000/static/js/bundle.js:1123:11)
    at useNavigateUnstable (http://localhost:3000/static/js/bundle.js:66522:102)
    at useNavigate (http://localhost:3000/static/js/bundle.js:66519:46)
    at App (http://localhost:3000/static/js/bundle.js:83:81)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:26618:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:29904:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:31200:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:16210:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:16254:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:16311:35)
ERROR
useNavigate() may be used only in the context of a <Router> component.
    at invariant (http://localhost:3000/static/js/bundle.js:1123:11)
    at useNavigateUnstable (http://localhost:3000/static/js/bundle.js:66522:102)
    at useNavigate (http://localhost:3000/static/js/bundle.js:66519:46)
    at App (http://localhost:3000/static/js/bundle.js:83:81)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:26618:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:29904:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:31200:20)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:36163:18)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:35432:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:35355:9)

问题代码

App.js

import logo from './logo.svg';
import './App.css';
import LoginForm from './components/LoginForm';
import SignUp from './signup';
import { BrowserRouter as Router, Routes, Route, Link, useNavigate } from 'react-router-dom';

function App() {
  const navigate = useNavigate();

  const handleSignUpClick = () => {
    navigate('/signup');
  }

  return (
    <Router>
      <div className="Login">
        <h3>
          <a className="nav-link active" aria-current="page" href="#" onClick={handleSignUpClick}>
            Sign up
          </a>
        </h3>
        <Routes>
          <Route path="/" element={<LoginForm />} />
          <Route path="/signup" element={<SignUp />} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;

LoginForm.js

import React, { useState } from 'react';
import { Button, Form, FormGroup, Label, Input, InputGroup } from 'reactstrap';
import { FaEye, FaEyeSlash } from 'react-icons/fa';

function LoginForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [showPassword, setShowPassword] = useState(false);

  const handleSubmit = (event) => {
    //handle submit
  }
  

  const toggleShowPassword = () => {
    setShowPassword(!showPassword);
  }

  return (
    <div className="form-box">
      <Form onSubmit={handleSubmit}>
        <FormGroup>
          <Label for="username">Username</Label>
          <Input type="text" name="username" id="username" value={username} onChange={e => setUsername(e.target.value)} />
        </FormGroup>
        <FormGroup>
          <Label for="password">Password</Label>
          <InputGroup>
            <Input type={showPassword ? 'text' : 'password'} name="password" id="password" value={password} onChange={e => setPassword(e.target.value)} />
            <Button onClick={toggleShowPassword}>
              {showPassword ? <FaEyeSlash /> : <FaEye />}
            </Button>
          </InputGroup>
        </FormGroup>
        <div className="text-center">
          <Button>Submit</Button>
        </div>
      </Form>
    </div>
  );
}

export default LoginForm;

SignUp.js

import './App.css';

function SignUp() {
  return (
    <div className="Login">
      <h1>Application</h1>
    </div>
  );
}

export default SignUp;

问题原因

你在App组件中直接调用了useNavigate(),但App组件是<Router>的父组件,此时useNavigate还未进入Router的上下文环境,所以触发了错误。

修复方案

方式一:用Link组件替代手动跳转(推荐)

React Router提供的<Link>组件是专门做路由跳转的,无需手动调用useNavigate,直接替换原有的<a>标签即可:

<Link className="nav-link active" aria-current="page" to="/signup">
  Sign up
</Link>

同时可以删掉useNavigate的导入和handleSignUpClick函数,代码更简洁。

方式二:将useNavigate移到Router内部组件中

如果一定要用useNavigate,可以把跳转逻辑抽成独立组件,这个组件必须放在<Router>内部:

// 新建跳转组件
function SignUpLink() {
  const navigate = useNavigate();
  const handleSignUpClick = () => {
    navigate('/signup');
  };
  return (
    <a className="nav-link active" aria-current="page" href="#" onClick={handleSignUpClick}>
      Sign up
    </a>
  );
}

// 在App的Router内部使用该组件
function App() {
  return (
    <Router>
      <div className="Login">
        <h3>
          <SignUpLink />
        </h3>
        <Routes>
          <Route path="/" element={<LoginForm />} />
          <Route path="/signup" element={<SignUp />} />
        </Routes>
      </div>
    </Router>
  );
}

完整修复后的App.js

import logo from './logo.svg';
import './App.css';
import LoginForm from './components/LoginForm';
import SignUp from './signup';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';

function App() {
  return (
    <Router>
      <div className="Login">
        <h3>
          <Link className="nav-link active" aria-current="page" to="/signup">
            Sign up
          </Link>
        </h3>
        <Routes>
          <Route path="/" element={<LoginForm />} />
          <Route path="/signup" element={<SignUp />} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:12:04