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

ReactRouter v6如何为特定路由指定父组件?

React Router v6 实现路由分组与布局隔离

核心思路

利用React Router v6的嵌套路由和路由保护组件,将页面分为两类:

  • 无需布局的全屏页面(登录、登出、404):直接挂载在根路由下
  • 需要共享布局的页面(用户中心、仪表盘、个人资料):嵌套在包含Header/Sidebar/Footer的布局组件中,同时添加登录校验

步骤1:创建共享布局组件

先定义包含公共UI的MainLayout,用<Outlet />渲染子页面内容:

import { Outlet } from 'react-router-dom';

function MainLayout() {
  return (
    <div className="app-layout">
      <Header /> {/* 你的标题栏组件 */}
      <div className="app-content">
        <Sidebar /> {/* 你的侧边栏组件 */}
        <div className="page-content">
          <Outlet /> {/* 子路由内容会渲染在这里 */}
        </div>
      </div>
      <Footer /> {/* 你的页脚组件 */}
    </div>
  );
}

步骤2:实现路由保护逻辑

创建两个路由控制组件,分别处理登录状态的跳转:

1. 登录校验组件(保护需要登录的页面)

import { Navigate, useLocation } from 'react-router-dom';
import { useAuth } from './useAuth'; // 自定义hook,获取登录状态

function RequireAuth({ children }) {
  const { isLoggedIn } = useAuth();
  const location = useLocation();

  // 未登录则跳转到登录页,记录当前位置以便登录后返回
  if (!isLoggedIn) {
    return <Navigate to="/login" state={{ from: location }} replace />;
  }

  return children;
}

2. 公共路由拦截(阻止已登录用户访问登录页)

import { Navigate, useLocation } from 'react-router-dom';
import { useAuth } from './useAuth';

function PublicRoute({ children }) {
  const { isLoggedIn } = useAuth();
  const location = useLocation();

  // 已登录用户访问登录页,自动跳转到首页或之前的位置
  if (isLoggedIn) {
    const redirectPath = location.state?.from?.pathname || '/';
    return <Navigate to={redirectPath} replace />;
  }

  return children;
}

步骤3:配置最终路由结构

将两类路由分别挂载,实现布局隔离和导航逻辑:

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import MainLayout from './MainLayout';
import RequireAuth from './RequireAuth';
import PublicRoute from './PublicRoute';

// 页面组件
import UserCenter from './UserCenter';
import Dashboard from './Dashboard';
import Profile from './Profile';
import SignIn from './SignIn';
import SignOut from './SignOut';
import NotFoundPage from './NotFoundPage';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        {/* 无需布局的全屏页面 */}
        <Route 
          path="/login" 
          element={
            <PublicRoute>
              <SignIn />
            </PublicRoute>
          } 
        />
        <Route path="/logout" element={<SignOut />} />
        <Route path="*" element={<NotFoundPage />} />

        {/* 需要共享布局的受保护页面 */}
        <Route 
          path="/" 
          element={
            <RequireAuth>
              <MainLayout />
            </RequireAuth>
          }
        >
          <Route index element={<UserCenter />} /> {/* 默认路由:/ */}
          <Route path="dashboard" element={<Dashboard />} /> {/* /dashboard */}
          <Route path="profile" element={<Profile />} /> {/* /profile */}
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

补充说明

  • 你需要自行实现useAuth hook,用来获取用户登录状态(可通过Context、Redux或Zustand等状态管理方案实现)。
  • 在SignOut组件中,处理完登出逻辑后,记得用useNavigate跳转到登录页:
    import { useNavigate } from 'react-router-dom';
    
    function SignOut() {
      const navigate = useNavigate();
    
      const handleLogout = () => {
        // 执行登出逻辑(清除token、用户信息等)
        navigate('/login', { replace: true });
      };
    
      return <button onClick={handleLogout}>登出</button>;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:58:56