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

react-router-dom v6.3.0中useNavigate()报‘not a function’错误求助

React Router DOM v6.3.0 useNavigate 钩子触发应用崩溃问题

我正在使用react-router-dom v6.3.0,遇到了useNavigate钩子触发应用崩溃的错误。已经完成基础排查:钩子位于函数组件内、组件已嵌套在路由中、package.json中react-router-dom版本为6.3.0,但问题仍未解决。以下是错误信息及相关代码,求解决。

错误信息

未捕获的类型错误:(0 , react__WEBPACK_IMPORTED_MODULE_0__.useNavigate) 不是一个函数
    在 LoginScreen (LoginScreen.js:9:1)
    在 renderWithHooks (react-dom.development.js:16305:1)
    在 mountIndeterminateComponent (react-dom.development.js:20074:1)
    在 beginWork (react-dom.development.js:21587:1)
    在 beginWork$1 (react-dom.development.js:27426:1)
    在 performUnitOfWork (react-dom.development.js:26557:1)
    在 workLoopSync (react-dom.development.js:26466:1)
    在 renderRootSync (react-dom.development.js:26434:1)
    在 recoverFromConcurrentError (react-dom.development.js:25850:1)
    在 performConcurrentWorkOnRoot (react-dom.development.js:25750:1)

相关代码

LoginScreen.js

import { useState, useEffect, useNavigate } from 'react'; //IMPORT USENAVIGATE HOOK
import axios from 'axios';
import { Link } from 'react-router-dom';


export default function LoginScreen() {

    const navigate = useNavigate();               //INITIALIZE USENAVIGATE HOOK

    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [error, setError] = useState('');

    //make sure they can't get to the login page if they're logged in
    useEffect(() => {
        if (localStorage.getItem('authToken')) {
            navigate('/');                          //CALL USENAVIGATE HOOK
        }
    }, [navigate])                          //PUT USENAVIGATE HOOK IN DEPENDENCY ARRAY

    const loginHandler = async (e) => {
        e.preventDefault();

        //set axios header
        const config = {
            header: {"Content-Type":"application/json"}
        }

        try {
            //make axios request to backend and desturcture data
            const { data } = await axios.post('/api/auth/login', { email, password}, config);

            localStorage.setItem("authToken", data.token);
            
            navigate('/');                          //CALL USENAVIGATE HOOK
        } catch (error) {
            setError(error.response.data.error)
            setTimeout(() => {
                setError('');
            }, 5000)
        }
    }

  return (
    <div className = "login">
        <form onSubmit = {loginHandler} className = "login-form">
            <h3 className = 'login-title'>Login</h3>
            
            {/*display error if error */}
            {error && <span className = "error-message">{error}</span>}


            {/* email group*/}
            <div className = 'form-group'>
                <label htmlFor = "email">Email</label>
                <input 
                    type = "text"
                    required
                    id = 'email'
                    placeholder = 'Enter your email address'
                    value = {email}
                    onChange = {(e) => setEmail(e.target.value)}
                />
            </div>

            {/* password group*/}
            <div className = 'form-group'>
                <label htmlFor = "password">Password</label>
                <input 
                    type = "password" /* i can probably use state to set this to text to make it visible*/
                    required
                    id = 'password'
                    placeholder = 'Enter a password'
                    value = {password}
                    onChange = {(e) => setPassword(e.target.value)}
                />
            </div>

            {/* submit*/}
            <button type = 'submit' className = 'btn btn-primary'>Login</button>

            {/*send to register */}
            <span className = 'login-span'>Don't have an account? <Link to = '/register'>Register</Link></span>
        </form>
    </div>
  )
}

App.js

//routes
import PrivateRoutes from './components/routing/PrivateRoutes';

//screens
import PrivateScreen from './components/screens/PrivateScreen';
import LoginScreen from './components/screens/LoginScreen';
import RegisterScreen from './components/screens/RegisterScreen';
import ForgotPasswordScreen from './components/screens/ForgotPasswordScreen';
import ResetPasswordScreen from './components/screens/ResetPasswordScreen';

const App = () => {
  return (
    <Router>
      <div classname = "app">
        <Routes>
          <Route path = '/' element = {localStorage.getItem('authToken') ? <PrivateScreen /> : <Navigate to = "/" />} />
          <Route path = '/login' element = {<LoginScreen />} />
          <Route path = '/register' element = {<RegisterScreen />} />
          <Route path = '/forgotpassword' element = {<ForgotPasswordScreen />} />
          <Route path = '/resetpassword' element = {<ResetPasswordScreen />} />
        </Routes>
      </div>
    </Router>
  )
}

export default App;

解决方案

1. 修正useNavigate的导入来源

useNavigate是react-router-dom提供的钩子,并非react内置。修改LoginScreen.js中的导入语句:

// 错误导入
import { useState, useEffect, useNavigate } from 'react';
// 正确导入
import { useState, useEffect } from 'react';
import { useNavigate, Link } from 'react-router-dom';

2. 补充App.js的路由组件导入

App.js中使用了<Router>、<Navigate>但未导入,需补充:

// 推荐使用BrowserRouter作为路由容器
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';

3. 修复根路由循环跳转问题

原根路由逻辑会导致未登录时无限跳转至自身,修改为跳转至登录页:

<Route path="/" element={localStorage.getItem('authToken') ? <PrivateScreen /> : <Navigate to="/login" />} />

4. 清理依赖缓存(可选)

若修改后问题仍存在,执行以下命令重装依赖:

rm -rf node_modules package-lock.json
npm install
npm start

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:27:28