You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用react-router-dom的useHistory触发reading 'push'未定义报错

报错根因分析

两个问题共同导致了该报错:

  • 第一:useHistory 钩子的调用位置错误
    useHistory 必须在 被<Router>包裹的后代组件 中调用才能拿到正确的history实例。你当前在App组件内调用useHistory,但App本身才是渲染<Router>的父组件,调用useHistory时外层还没有Router上下文,所以返回的history是undefined,调用push方法自然抛出TypeError。
  • 第二:三元表达式内的跳转逻辑写法错误
    你在loggedIn为true时返回的是箭头函数() => history.push('/'),既不会执行跳转逻辑,也不符合React组件返回值要求,就算history正常也不会生效。

修复方案

方法1:拆分组件,把需要用history的逻辑放到Router内部的子组件

把路由判断逻辑抽成单独的内部组件,放在<Router>内部调用,就能正常拿到history:

import './App.css';
import { React, useState } from 'react'
import Header from './Header';
import Register from './Register';
import Login from './Login';
import { BrowserRouter as Router, Switch, Route, useHistory } from 'react-router-dom'

// 抽离内部路由组件
function RoutesContent({ loggedIn, setLoggedIn }) {
  const history = useHistory()
  // 登录状态生效时直接执行跳转,不要在JSX返回值里写跳转逻辑
  if (loggedIn && window.location.pathname === '/log-in') {
    history.push('/')
    return null
  }
  return (
    <Switch>
      <Route exact path='/'>
        {loggedIn ? <h1>Logged In</h1> : <Register setLoggedIn={setLoggedIn} />}
      </Route>
      <Route path='/log-in'>
        <Login setLoggedIn={setLoggedIn} loggedIn={loggedIn} />
      </Route>
    </Switch>
  )
}

function App() {
  const [ loggedIn, setLoggedIn ] = useState(false)

  return (
    <Router>
      <Header />
      <RoutesContent loggedIn={loggedIn} setLoggedIn={setLoggedIn} />
    </Router>
  );
}

export default App;

方法2:适配react-router-dom v6版本

如果你的项目依赖是v6版本的react-router-dom,useHistory已经被移除,替换为useNavigate,用法如下:

import { useNavigate } from 'react-router-dom'
// 在符合上下文要求的组件内调用
const navigate = useNavigate()
navigate('/') // 等价于v5版本的history.push('/')

内容的提问来源于stack exchange,提问作者Justin Christopher Domingo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 14:39:03