React Router中useNavigate在BrowserRouter内仍报错问题
错误根源
你在App组件的顶层直接调用useNavigate(),但此时BrowserRouter还未完成渲染。useNavigate必须在BrowserRouter提供的路由上下文范围内才能使用,因此触发了错误。
解决方案
方案一:将BrowserRouter移到App组件外部
在项目入口文件(比如index.js)中用BrowserRouter包裹App组件,确保App全程处于路由上下文内:
import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <BrowserRouter> <App /> </BrowserRouter> );
此时App组件可正常调用useNavigate:
function App() { const navigate = useNavigate(); return ( <main dir="rtl" lang="fa"> <header> <NavBar /> </header> <Routes> <Route index element={<ElectricalPanel onClick={() => navigate("efuse/")} />} /> {/* 其他路由保持原有配置 */} </Routes> </main> ); }
方案二:在App内部创建嵌套组件调用useNavigate
如果不想修改入口文件,可以在App内部新建子组件,将useNavigate的调用放在这个子组件中(该子组件处于BrowserRouter内部):
function App() { return ( <BrowserRouter> <AppContent /> </BrowserRouter> ); } // 子组件处于BrowserRouter上下文内,可正常使用useNavigate function AppContent() { const navigate = useNavigate(); return ( <main dir="rtl" lang="fa"> <header> <NavBar /> </header> <Routes> <Route index element={<ElectricalPanel onClick={() => navigate("efuse/")} />} /> {/* 其他路由保持原有配置 */} </Routes> </main> ); }
优化建议:组件内直接使用useNavigate
无需通过props传递跳转逻辑,每个路由组件可直接导入useNavigate并使用,代码更简洁:
import { useNavigate } from 'react-router-dom'; import { useState } from 'react'; const Screw = () => { const navigate = useNavigate(); const [count, setCount] = useState(null); const handleSubmit = () => { navigate("/"); } return ( <div> <h1>پیچ</h1> <div className="fuse-container"> <div className="fuse-option" onChange={(e) => setCount(parseInt(e.target.value))} > <label htmlFor="count">تعداد بسته پیچ را وارد کنید:</label> <input type="number" id="count" /> </div> </div> <div>{count > 0 && <button onClick={handleSubmit}>تایید</button>}</div> </div> ); };
对应的路由配置也可简化,无需传递onClick props:
<Route path="screw/" element={<Screw />} />
内容的提问来源于stack exchange,提问作者Seyedmahdi moosavyan
相关产品推荐
相关产品推荐

