React路由中Invalid Hook call错误的排查与解决
React路由使用中遇到无效Hook调用错误
错误信息
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. at Object.throwInvalidHookError (react-dom.development.js:16227:1) at Object.useContext (react.development.js:1618:1) at useInRouterContext (hooks.tsx:85:1) at Navigate (components.tsx:196:1) at Login.jsx:24:1
项目组件代码
Login.jsx
import React, { useState } from "react"; import { useLocation } from "react-router-dom"; import { Navigate } from "react-router-dom"; const Login = () => { const location = useLocation(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [errorMessage, setErrorMessage] = useState(""); const submitForm = (event) => { event.preventDefault(); fetch("http://localhost:8000/users") .then((response) => response.json()) .then((data) => { const user = data.find( (user) => user.email && user.email.toLowerCase() === email.toLowerCase() && user.password && user.password.toLowerCase() === password.toLowerCase() ); if (user) { Navigate("/profile"); } else { setErrorMessage("Invalid email or password"); } }) .catch((error) => console.log(error)); }; return ( <div> <form onSubmit={submitForm}> <div> <label htmlFor="email">Enter Email Address:</label> <input type="text" name="email" id="email" value={email} onChange={(e) => setEmail(e.target.value)} /> </div> <div> <label htmlFor="password">Enter Password:</label> <input type="password" name="password" id="password" value={password} onChange={(e) => setPassword(e.target.value)} /> </div> <button type="submit">Login</button> </form> {errorMessage && <p>{errorMessage}</p>} </div> ); }; export default Login;
App.jsx
import React from "react"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Profile from "./components/Profile"; import Login from "./components/Login"; function App() { return ( <div className="wrapper"> <h1>Application</h1> <Router> <Routes> <Route path="/" element={<Login />} /> <Route path="/profile" element={<Profile />} /> </Routes> </Router> </div> ); } export default App;
Profile.jsx
import React from "react"; const Profile = () => { return ( <div> <h2>Dashboard</h2> <p>Welcome to your profile page!</p> {/* Display user profile information here */} </div> ); }; export default Profile;
已尝试的修复方法
- 重装VSCode/Node.js
- 新建React项目
- 使用
npm link ../myapp/node_modules/react命令
当前React版本信息
PS C:\Users\Admin\Documents\SD Semester2\Final_Sprint\finalsprint> npm ls react finalsprint@0.1.0 C:\Users\Admin\Documents\SD Semester2\Final_Sprint\finalsprint ├─┬ @testing-library/react@13.4.0 ├─┬ react-dom@18.2.0 │ └── react@18.2.0 deduped ├─┬ react-router-dom@6.10.0 │ └── react@18.2.0 deduped ├─┬ react-router@6.10.0 │ └── react@18.2.0 deduped ├─┬ react-scripts@5.0.1 │ └── react@18.2.0 deduped └── react@18.2.0
另外,在浏览器控制台执行React.version时提示React未定义。
问题原因与修复方案
核心问题
你在Login组件的submitForm函数里直接调用Navigate("/profile"),但Navigate是React组件,不是普通函数。这种调用方式会触发组件内部的Hook执行,而Hook只能在函数组件的顶层作用域调用,违反了Hook规则,因此抛出错误。
修复步骤
- 替换
Navigate导入为useNavigate钩子:import { useLocation, useNavigate } from "react-router-dom"; - 在
Login组件顶层初始化导航函数:const Login = () => { const location = useLocation(); const navigate = useNavigate(); // 新增此行 // ...其他状态定义 - 修改登录成功后的跳转逻辑,使用
navigate函数:if (user) { navigate("/profile"); // 替换原来的Navigate("/profile") }
额外说明
浏览器控制台无法访问React是因为生产环境下React会被压缩且不暴露全局变量,开发环境可通过window.React查看,但这和当前Hook错误无关。你的版本信息显示所有依赖的React版本一致,不存在多版本或版本不匹配的问题,核心问题就是错误使用Navigate组件。
内容的提问来源于stack exchange,提问作者jonooo
相关产品推荐
相关产品推荐

