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

React Typescript报错:在<Router>外使用<withRouter(App)>该如何解决?

问题根因

报错的核心原因是React Router提供的withRouter高阶组件、useHistory钩子都只能在被<Router>组件包裹的后代组件中调用,你当前的代码结构存在顺序错误:你在<App>组件内部才渲染<Router>,但是<App>本身先被withRouter封装,还在组件顶层调用了useHistory,相当于路由上下文还没初始化就提前调用了路由相关API,自然触发报错。


修复步骤

  1. 把<Router>组件从App.tsx中移到项目入口文件(通常是index.tsx),用来包裹整个App组件,保证App内部所有组件都能拿到路由上下文
  2. 删除App组件的withRouter封装,函数组件直接使用useHistory即可,无需额外包裹高阶组件
  3. 补全useEffect的依赖项,避免逻辑重复触发

入口文件index.tsx参考代码

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store'; // 替换为你实际的store路径

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
  <Provider store={store}>
    {/* Router移到此处包裹App */}
    <Router>
      <App />
    </Router>
  </Provider>
);

修改后App.tsx代码

import React, { FC, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import {
  Route,
  Switch,
  useHistory,
} from "react-router-dom";
import "./App.css";

import Header from "./components/sections/Header";
import SignUp from "./components/pages/SignUp";
import SignIn from "./components/pages/SignIn";
import ForgotPassword from "./components/pages/ForgotPassword";
import Homepage from "./components/pages/Homepage";
import Dashboard from "./components/pages/Dashboard";
import PrivateRoute from "./components/auth/PrivateRoute";
import PublicRoute from "./components/auth/PublicRoute";
import Loader from "./components/UI/Loader";
import firebase from "./firebase/config";
import {
  getUserById,
  setLoading,
  setNeedVerification,
} from "./store/actions/authActions";
import { RootState } from "./store";

const App: FC = () => {
  const dispatch = useDispatch();
  const { loading } = useSelector((state: RootState) => state.auth);
  const history = useHistory();

  useEffect(() => {
    dispatch(setLoading(true));
    const unsubscribe = firebase.auth().onAuthStateChanged(async (user) => {
      if (user) {
        await dispatch(getUserById(user.uid));
        if (user.emailVerified) {
          history.push("/homepage");
        } else {
          history.push("/signin");
          dispatch(setNeedVerification());
        }
      }
      dispatch(setLoading(false));
    });

    return () => {
      unsubscribe();
    };
  // 补全依赖项避免重复执行
  }, [dispatch, history]);

  if (loading) {
    return <Loader />;
  }

  function Routes() {
    return (
      <Switch>
        <PublicRoute path="/signup" component={SignUp} exact />
        <PublicRoute path="/signin" component={SignIn} exact />
        <PublicRoute path="/forgot-password" component={ForgotPassword} exact />
        <PrivateRoute path="/dashboard" component={Dashboard} exact />
        <PublicRoute path="/homepage" component={Homepage} exact />
      </Switch>
    );
  }
  // 去掉外层Router标签,已经在入口文件包裹
  return (
    <>
      <Header />
      <Routes />
    </>
  );
};
// 去掉withRouter封装
export default App;

内容的提问来源于stack exchange,提问作者Manuel Lucas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:06:02