React+TypeScript中useHistory的使用方法及路由跳转报错解决方案咨询
解决React+TypeScript中useHistory报错:Cannot read property 'push' of undefined
问题根源
你碰到的这个错误核心原因很明确:useHistory钩子只能在被BrowserRouter(或其他路由上下文提供者)包裹的组件里正常工作。你的Topbar组件是在BrowserRouter外部渲染的,完全没接触到路由上下文,所以history变量拿到的是undefined,调用push方法自然就报错了。
解决方案
方案1:把Topbar移到BrowserRouter内部
这是最直接省心的解决方式,调整App.tsx的结构,让Topbar处于路由上下文的覆盖范围内:
// App.tsx import "./styles/app.scss"; import {BrowserRouter, Route, Switch, Redirect} from 'react-router-dom' function App() { return ( <div className = "app"> <section> <BrowserRouter> {/* 将Topbar移入BrowserRouter内部 */} <Topbar/> <Switch> <Route exact = {true} path = "/" component = {Home}/> <Route path = "/mypage" component = {Mypage}/> <Route path = "/registerpage" component = {RegisterPage}/> {/* Not Found */} <Route component = {() => <Redirect to = "/" />} /> </Switch> </BrowserRouter> </section> </div> ); }
修改后,Topbar就能正常通过useHistory获取到路由对象,点击跳转的逻辑就能正常运行了。
方案2:用withRouter高阶组件(适配React Router v5)
如果因为布局需求不想移动Topbar的位置,可以用withRouter把组件包裹起来,强制让它能访问到路由上下文:
先修改Topbar.tsx:
// Topbar.tsx import { withRouter, RouteComponentProps } from 'react-router-dom'; import { FaUserCircle } from 'react-icons/fa'; // 通过RouteComponentProps继承路由相关属性的类型 function Topbar({ history }: RouteComponentProps) { return ( <header className="topbar"> <button className="account_logo"> <FaUserCircle className="logo" onClick={() => {history.push('/mypage')}}/> </button> </header> ); } // 用withRouter包裹组件,注入路由上下文 export default withRouter(Topbar);
之后确保App.tsx中导入的是被withRouter包裹后的Topbar组件,这样哪怕它在BrowserRouter外部,也能拿到正常的history对象。
TypeScript类型优化提示
为了让类型检查更严谨,你可以显式指定history的类型:
import { History } from 'history'; import { RouteComponentProps } from 'react-router-dom'; // 或者直接解构并指定类型 function Topbar({ history }: { history: History }) { // ...组件逻辑 }
这样在调用history.push时,TypeScript会提供更精准的类型提示,避免潜在的类型错误。
内容的提问来源于stack exchange,提问作者sunpl13
相关产品推荐
相关产品推荐

