在 React Router 中利用 Outlet 实现组件嵌套渲染

理解 React Router 的 Outlet 组件

在构建复杂的单页应用时,我们经常需要在一个父组件(例如一个布局组件,包含侧边栏和头部导航)的特定区域内动态地渲染不同的子组件。React Router v6 引入的 Outlet 组件正是为解决这一问题而设计的。它充当一个占位符,用于渲染当前匹配到的子路由所对应的组件。这意味着,当你的路由结构存在嵌套关系时,父路由组件可以使用 Outlet 来指定其子路由组件的渲染位置,而无需在父组件内部编写复杂的条件渲染逻辑。

实现组件嵌套渲染的步骤

要将 组件渲染到 Dashboard 组件的 .main-content div 中,我们需要进行以下两步关键修改:

1. 修改父组件 Dashboard

Dashboard 组件将作为布局容器,它需要明确指出子路由组件应该在哪里被渲染。为此,我们将在 Dashboard 组件的 .main-content div 内部添加 Outlet 组件。

修改前的 Dashboard.js 片段:

import React,{useState} from 'react'
import { Outlet } from 'react-router-dom'; // 确保引入了 Outlet
import AdminSidebar from '../AdminSidebar/AdminSidebar'
import AdminHeader from '../AdminHeader/AdminHeader';
import "./Dashboard.css"

function Dashboard() {
  // ... 其他状态和逻辑 ...

  return (
    <>
      
      
        
        {/* 这里是需要渲染子组件的位置 */}
      

      {/* ... 其他元素 ... */}
    
  )
}

export default Dashboard

修改后的 Dashboard.js 片段:

import React,{useState} from 'react'
import { Outlet } from 'react-router-dom'; // 确保引入了 Outlet
import AdminSidebar from '../AdminSidebar/AdminSidebar'
import AdminHeader from '../AdminHeader/AdminHeader';
import "./Dashboard.css"

function Dashboard() {
  const [checkboxChecked, setCheckboxChecked] = useState(false);
  // ... 其他 handleCheckboxChange 和 handleToggleClick 逻辑 ...

  return (
    <>
      
      
        
         {/* 在这里渲染嵌套路由的组件 */}
      

      
      
    
  )
}

export default Dashboard

通过在 .main-content div 中添加 ,我们告诉 React Router:当 Dashboard 组件的子路由被激活时,将子路由对应的组件渲染到这个 Outlet 的位置。

2. 配置 App.js 中的嵌套路由

在 App.js 中,我们需要重新组织路由结构,将 Dashboard 设为一个父路由,并将其下的 AdminMain 和 AddProduct 作为子路由。

修改前的 App.js 片段:

// ... 其他 import ...
import Dashboard from './Admin/Dashboard/Dashboard';
import AdminMain from './Admin/AdminMain/AdminMain';
import AddProduct from './Admin/AddProduct/AddProduct';
// ... 其他组件和状态 ...

function App() {
  // ... 其他逻辑 ...

  return (
    <>
      
        {adminRoute ?   : 
} }/> }/> ); } export default App;

修改后的 App.js 片段:

// ... 其他 import ...
import Dashboard from './Admin/Dashboard/Dashboard';
import AdminMain from './Admin/AdminMain/AdminMain';
import AddProduct from './Admin/AddProduct/AddProduct';
// ... 其他组件和状态 ...

function App() {
  // ... 其他逻辑 ...

  return (
    <>
      
        {/* 这里的条件渲染可以保留,用于在非admin路径下显示Header,在admin路径下显示Dashboard */}
        {adminRoute ? null : 
} } /> } /> {/* 定义Dashboard作为父路由,其路径为 /admin/* */} }> {/* 子路由路径相对于父路由 */} {/* 可以添加一个默认子路由,例如 index */} {/* */} ); } export default App;

关键点说明:

  1. 父路由的 path 属性: 将 Dashboard 组件的路由路径设置为 /admin/*。这里的 * 是一个通配符,表示该路径下的所有子路径都将由 Dashboard 路由处理。
  2. 子路由的 path 属性: 子路由的 path 属性是相对于其父路由的。例如,} />)。