如何结合react-router-dom实现Material UI Tabs同页面路由切换
实现Material UI VerticalTabs与react-router-dom集成(URL更新不跳转)
步骤说明
先确保已安装
react-router-dom,未安装则执行:npm install react-router-dom # 或 yarn add react-router-dom用
BrowserRouter包裹根组件(如App.js),确保路由上下文生效:import { BrowserRouter } from 'react-router-dom'; function App() { return ( <BrowserRouter> <VerticalTabs /> </BrowserRouter> ); }修改VerticalTabs组件,集成路由逻辑:
- 用
useNavigate实现无跳转的URL更新 - 用
useLocation获取当前URL路径,同步Tab选中状态 - 给每个Tab绑定对应路径,点击时同步更新URL和Tab状态
- 用
修改后的完整代码
import * as React from 'react'; import PropTypes from 'prop-types'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import { useNavigate, useLocation } from 'react-router-dom'; // 统一管理Tab标签与对应路由路径 const TAB_ROUTES = [ { label: 'Item One', path: '/item-one' }, { label: 'Item Two', path: '/item-two' }, { label: 'Item Three', path: '/item-three' }, ]; function TabPanel(props) { const { children, value, index, ...other } = props; return ( <div role="tabpanel" hidden={value !== index} id={`vertical-tabpanel-${index}`} aria-labelledby={`vertical-tab-${index}`} {...other} > {value === index && ( <Box sx={{ p: 3 }}> <Typography>{children}</Typography> </Box> )} </div> ); } TabPanel.propTypes = { children: PropTypes.node, index: PropTypes.number.isRequired, value: PropTypes.number.isRequired, }; function a11yProps(index) { return { id: `vertical-tab-${index}`, 'aria-controls': `vertical-tabpanel-${index}`, }; } export default function VerticalTabs() { const navigate = useNavigate(); const location = useLocation(); // 根据当前URL路径初始化Tab选中索引 const currentTabIndex = TAB_ROUTES.findIndex(tab => tab.path === location.pathname); const [value, setValue] = React.useState(currentTabIndex === -1 ? 0 : currentTabIndex); const handleChange = (event, newValue) => { setValue(newValue); // 更新URL,不触发页面跳转 navigate(TAB_ROUTES[newValue].path); }; return ( <Box sx={{ flexGrow: 1, bgcolor: 'background.paper', display: 'flex', height: 224 }} > <Tabs orientation="vertical" variant="scrollable" value={value} onChange={handleChange} aria-label="Vertical tabs example" sx={{ borderRight: 1, borderColor: 'divider' }} > {TAB_ROUTES.map((tab, index) => ( <Tab key={index} label={tab.label} {...a11yProps(index)} /> ))} </Tabs> {TAB_ROUTES.map((tab, index) => ( <TabPanel key={index} value={value} index={index}> {tab.label} </TabPanel> ))} </Box> ); }
关键逻辑说明
TAB_ROUTES:集中管理Tab信息,避免硬编码,便于后续修改维护useLocation:获取当前URL路径,保证页面刷新后Tab状态与URL一致useNavigate:调用该方法更新URL时,只会修改地址栏,不会触发页面跳转- 初始化
value:从URL匹配对应Tab索引,支持直接通过路由链接访问指定Tab面板
内容的提问来源于stack exchange,提问作者sultan.h
相关产品推荐
相关产品推荐

