如何在BrowserRouter外部的持久化Header中使用react-router-dom跳转组件
修复方案及根因
报错根因
所有react-router-dom提供的路由Hook(包括useHistory、useLocation等),只能在<BrowserRouter>(即你代码里重命名的Router)包裹的子组件内部调用,才能访问到路由上下文。你的代码里<Router>仅包裹了页面路由部分,全局header以及App组件本身都不在<Router>的上下文范围内,所以在App组件内调用useHistory时,获取不到history对象,直接抛出undefined错误。
代码修正
你只需要把<Router>移到最外层,包裹所有需要用到路由能力的节点即可,header组件也可以全局复用,无需在每个页面单独引入:
环境初始化命令(保持不变)
npx create-react-app rdr-header --template typescript npm install react-router-dom
修正后完整App.tsx代码
import React from "react"; import "./App.css"; import { BrowserRouter as Router, Switch, Route, useHistory, } from "react-router-dom"; function App() { return ( // Router移到最外层,包裹所有需要用到路由能力的节点 <Router> <div className='App'> {/* 全局常驻header,只需引入一次 */} <header className='App-header'> <HeaderButtons /> </header> <Switch> <Route exact path='/' component={English} /> <Route path='/ger' component={German} /> </Switch> </div> </Router> ); } // 抽离header按钮组件,内部调用useHistory获取路由上下文 const HeaderButtons = () => { const history = useHistory(); const handleClick = (to: string) => { history.push(to); }; return ( <> <button onClick={() => handleClick("/ger")}>German</button> <button onClick={() => handleClick("/")}>English</button> </> ) } const English = () => { let history = useHistory(); const handleClick = () => { history.push("/ger"); }; return ( <> <h1>English</h1> <button onClick={handleClick}>跳转到德语页</button> </> ); }; const German = () => { let history = useHistory(); const handleClick = () => { history.push("/"); }; return ( <> <h1>German</h1> <button onClick={handleClick}>跳转到英语页</button> </> ); }; export default App;


内容的提问来源于stack exchange,提问作者Jay Cork
相关产品推荐
相关产品推荐

