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

React Router嵌套路由异常:404与FixedDrawer跳转冲突问题求助

解决React嵌套路由的Exact与404跳转冲突问题

这个问题我之前在项目里也碰到过,核心是嵌套路由里exact的使用和Switch的匹配顺序没处理好,给你一套完整的解决方案:

问题根源分析

  1. 当你给根路由添加exact属性时,它会严格匹配路径/,导致所有子路由(比如/users、/databases)无法匹配到父路由的组件,所以FixedDrawer里的Link跳转后找不到对应的页面组件。
  2. 不加exact的话,如果NotFound组件的路由没有放在Switch的最后,会因为模糊匹配被提前触发,导致所有页面都显示404。

解决方案:重构路由层级与匹配顺序

1. 实现鉴权路由组件(PrivateRoute)

先封装一个通用的鉴权路由组件,用来处理未认证用户的重定向:

import { Route, Redirect } from 'react-router-dom';

const PrivateRoute = ({ component: Component, ...rest }) => {
  // 替换成你的实际认证逻辑,比如从Context、LocalStorage或Redux获取
  const isAuthenticated = localStorage.getItem('token') !== null;

  return (
    <Route
      {...rest}
      render={(props) =>
        isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect to="/login" />
        )
      }
    />
  );
};

export default PrivateRoute;

2. 调整主路由结构

用Switch包裹所有路由,严格控制匹配顺序,把NotFound放在最后,根路由不需要加exact:

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import PrivateRoute from './PrivateRoute';
import Login from './Login';
import Dashboard from './Dashboard';
import NotFound from './NotFound';

function App() {
  return (
    <Router>
      <Switch>
        {/* 公开路由:登录页 */}
        <Route path="/login" component={Login} />
        {/* 鉴权路由:所有非登录的路径都进入Dashboard */}
        <PrivateRoute path="/" component={Dashboard} />
        {/* 404页面:必须放在Switch的最后,只有前面的路由都不匹配时才触发 */}
        <Route component={NotFound} />
      </Switch>
    </Router>
  );
}

export default App;

3. 配置Dashboard内的嵌套路由

在FixedDrawer所在的Dashboard组件里,用内部的Switch处理子路由,确保Link的路径能正确匹配:

import { Switch, Route, Link } from 'react-router-dom';
import FixedDrawer from './FixedDrawer';
import Home from './Home';
import Users from './Users';
import Databases from './Databases';

function Dashboard() {
  return (
    <div className="dashboard-container">
      <FixedDrawer>
        {/* 这里的Link路径要和子路由的path对应 */}
        <Link to="/">首页</Link>
        <Link to="/users">用户管理</Link>
        <Link to="/databases">数据库列表</Link>
      </FixedDrawer>
      {/* 内部Switch处理子路由 */}
      <Switch>
        <Route path="/users" component={Users} />
        <Route path="/databases" component={Databases} />
        {/* 默认首页:匹配根路径 */}
        <Route path="/" component={Home} />
      </Switch>
    </div>
  );
}

export default Dashboard;

为什么这样能解决问题?

  • 主路由的Switch会按顺序匹配:先匹配/login,然后匹配所有以/开头的路径进入Dashboard,最后才会触发NotFound,完美实现404功能,不需要给任何路由加exact。
  • Dashboard内部的Switch会处理具体的子路由,FixedDrawer里的Link跳转后,路径能被内部的Route正确匹配,不会因为父路由的exact属性而失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:20:57