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

React新手求助:如何通过侧边栏链接切换主区域组件?

实现带Navbar、Sidebar和内容切换的React页面

嘿,作为React新手,你要做的这个页面其实很容易搞定,我来给你一套完整的解决方案,顺便把你发现的那个路由坑也讲透~

首先,你需要用到React Router来实现组件的路由切换,先确保已经安装了依赖:

npm install react-router-dom
# 或者用yarn
yarn add react-router-dom

React Router v6 完整代码示例(推荐,当前主流版本)

UserPage 主页面

import { BrowserRouter as Router, Routes, Route, Outlet } from 'react-router-dom';
import Sidebar from '../Sidebar';
import Navbar from '../Navbar';
import { Page1, Page2, Page3 } from './menu';

export default function UserPage() {
  return (
    <Router>
      {/* Navbar和Sidebar会在所有路由页面保持显示 */}
      <Navbar />
      <div style={{ display: 'flex', minHeight: 'calc(100vh - 60px)' }}>
        <Sidebar />
        {/* 主内容区域:Outlet会自动渲染当前匹配的子路由组件 */}
        <div style={{ flex: 1, padding: '1rem' }}>
          <Outlet />
        </div>
      </div>

      {/* 配置所有路由规则 */}
      <Routes>
        {/* 默认打开Page1 */}
        <Route path="/" element={<Page1 />} />
        <Route path="/page1" element={<Page1 />} />
        <Route path="/page2" element={<Page2 />} />
        <Route path="/page3" element={<Page3 />} />
      </Routes>
    </Router>
  );
}
import { NavLink } from 'react-router-dom';

export default function Sidebar() {
  return (
    <div style={{ width: '220px', backgroundColor: '#f8f9fa', padding: '1.5rem' }}>
      <h3 className="mb-4">导航菜单</h3>
      <ul style={{ listStyle: 'none', paddingLeft: 0 }}>
        <li className="mb-3">
          <NavLink 
            to="/page1"
            style={({ isActive }) => ({
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: isActive ? '#fff' : '#333',
              backgroundColor: isActive ? '#0d6efd' : 'transparent',
              textDecoration: 'none'
            })}
          >
            页面1
          </NavLink>
        </li>
        <li className="mb-3">
          <NavLink 
            to="/page2"
            style={({ isActive }) => ({
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: isActive ? '#fff' : '#333',
              backgroundColor: isActive ? '#0d6efd' : 'transparent',
              textDecoration: 'none'
            })}
          >
            页面2
          </NavLink>
        </li>
        <li className="mb-3">
          <NavLink 
            to="/page3"
            style={({ isActive }) => ({
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: isActive ? '#fff' : '#333',
              backgroundColor: isActive ? '#0d6efd' : 'transparent',
              textDecoration: 'none'
            })}
          >
            页面3
          </NavLink>
        </li>
      </ul>
    </div>
  );
}

关键细节说明

  1. 路由结构逻辑:
    我们把Navbar和Sidebar放在Routes外面,这样它们会在所有路由页面中持续显示。主内容用Outlet组件承接,它会自动匹配当前路由并渲染对应的页面组件(Page1/Page2/Page3)。

  2. 你发现的那个坑!:
    如果你用的是React Router v5版本,千万不要给根路径path="/"添加exact属性!因为加了exact后,只有访问/时才会匹配该路由,当你跳转到/page1这类子路径时,根路由不会被触发,Navbar和Sidebar就会消失。而在v6版本里,exact已经被移除了,路由默认是精确匹配,但我们的结构是把公共组件放在路由规则外,所以不用操心这个问题~

如果你用的是React Router v5(旧版本)

UserPage 主页面

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Sidebar from '../Sidebar';
import Navbar from '../Navbar';
import { Page1, Page2, Page3 } from './menu';

export default function UserPage() {
  return (
    <Router>
      <Navbar />
      <div style={{ display: 'flex', minHeight: 'calc(100vh - 60px)' }}>
        <Sidebar />
        <div style={{ flex: 1, padding: '1rem' }}>
          <Switch>
            <Route path="/page1" component={Page1} />
            <Route path="/page2" component={Page2} />
            <Route path="/page3" component={Page3} />
            {/* 根路由不要加exact!否则子路径不会加载公共组件 */}
            <Route path="/" component={Page1} />
          </Switch>
        </div>
      </div>
    </Router>
  );
}
import { NavLink } from 'react-router-dom';

export default function Sidebar() {
  return (
    <div style={{ width: '220px', backgroundColor: '#f8f9fa', padding: '1.5rem' }}>
      <h3 className="mb-4">导航菜单</h3>
      <ul style={{ listStyle: 'none', paddingLeft: 0 }}>
        <li className="mb-3">
          <NavLink 
            to="/page1"
            activeStyle={{
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: '#fff',
              backgroundColor: '#0d6efd',
              textDecoration: 'none'
            }}
            style={{
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: '#333',
              textDecoration: 'none'
            }}
          >
            页面1
          </NavLink>
        </li>
        <li className="mb-3">
          <NavLink 
            to="/page2"
            activeStyle={{
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: '#fff',
              backgroundColor: '#0d6efd',
              textDecoration: 'none'
            }}
            style={{
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: '#333',
              textDecoration: 'none'
            }}
          >
            页面2
          </NavLink>
        </li>
        <li className="mb-3">
          <NavLink 
            to="/page3"
            activeStyle={{
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: '#fff',
              backgroundColor: '#0d6efd',
              textDecoration: 'none'
            }}
            style={{
              display: 'block',
              padding: '0.5rem',
              borderRadius: '4px',
              color: '#333',
              textDecoration: 'none'
            }}
          >
            页面3
          </NavLink>
        </li>
      </ul>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:18:26