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

如何结合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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:31:20