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> ); }
Sidebar 侧边栏组件
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> ); }
关键细节说明
路由结构逻辑:
我们把Navbar和Sidebar放在Routes外面,这样它们会在所有路由页面中持续显示。主内容用Outlet组件承接,它会自动匹配当前路由并渲染对应的页面组件(Page1/Page2/Page3)。你发现的那个坑!:
如果你用的是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> ); }
Sidebar 侧边栏组件(v5版本)
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
相关产品推荐
相关产品推荐

