使用React Router Dom时遇空白页及无效Hook调用错误求助
问题现象
使用React Router Dom时页面空白,控制台抛出Invalid Hook Call警告,错误指向<BrowserRouter>组件。
控制台报错信息
react.development.js:209 Warning: 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
The above error occurred in the
component: at BrowserRouter (http://localhost:3000/static/js/bundle.js:5179:5) at App (http://localhost:3000/static/js/bundle.js:44:74)Consider adding an error boundary to your tree to customize error handling behavior.
npm依赖检查结果
执行npm ls react输出:
PS C:\Users\MAHELAKA\React> npm ls react React@ C:\Users\MAHELAKA\React └─┬ react-router-dom@6.10.0 ├─┬ react-dom@18.2.0 │ └── react@18.2.0 deduped ├─┬ react-router@6.10.0 │ └── react@18.2.0 deduped └── react@18.2.0
现有App.js代码
import "./App.css"; import Alert from "./components/Alert"; import About from "./components/About"; import Navbar from "./components/Navbar"; import TextForm from "./components/TextForm"; import React, { useState } from "react"; import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom"; // import About from "./components/About" function App(props) { const [mode, setMode] = useState("light"); const [alert, setAlert] = useState(null); const showAlert = (message, type) => { setAlert({ msg: message, type: type }); setTimeout(() => { setAlert(null); }, 2000); }; const toggleMode = () => { if (mode === "light") { setMode("dark"); document.body.style.backgroundColor = "#011121"; document.body.style.color = "white"; showAlert("dark mode has been enabled", "success"); document.title = 'TextUtils - Dark Mode' } else { setMode("light"); document.body.style.backgroundColor = "white"; document.body.style.color = "black"; showAlert("white mode has been enabled", "success"); document.title = 'TextUtils - Light Mode' } }; return ( <> <Router> <Alert alert={alert} /> <div className="container my-3"> <Routes> <Route path="/about" element={<About/>} /> <Route path="/" element={<TextForm showAlert={showAlert} heading="Enter The Text To Analyze Below" />} /> </Routes> </div> </Router> </> ); } export default App;
解决方案
从依赖结果看,React版本统一为18.2.0,排除多版本冲突问题,重点排查Hook使用规则和缓存问题:
1. 检查自定义组件的Hook使用
逐一验证Alert、About、TextForm等组件:
- 确保所有组件都是函数组件,禁止在类组件中使用Hook
- 所有Hook调用必须放在组件的顶层作用域,不能嵌套在条件判断、循环、嵌套函数中
- 示例正确的Alert组件写法:
import React from 'react'; function Alert({ alert }) { // Hook必须在组件顶层,不能在if/for等代码块内 return ( <div> {alert && <div className={`alert alert-${alert.type}`} role="alert"> {alert.msg} </div>} </div> ); } export default Alert;
2. 清理依赖缓存并重装
执行以下命令清除缓存,修复可能的依赖损坏问题:
npm cache clean --force rm -rf node_modules package-lock.json npm install
3. 确认React DOM版本匹配
执行npm ls react-dom,确保其版本为18.2.0,与React主版本完全一致。
4. 验证路由包裹层级
当前代码中Router的包裹范围是正确的,但需确保没有在Router外部使用路由相关Hook(如useNavigate、useParams等)。
总结
最可能的根源是某个自定义组件违反了Hook使用规则,或是依赖缓存导致的隐性版本问题。先清理依赖缓存,再逐一检查组件内部的Hook调用逻辑,确保所有Hook都符合规则。
内容的提问来源于stack exchange,提问作者Mahelaka Mansoori

