首页 > 解决方案 > 如何在 Ant Design Tab 组件中使用 React Router Link 组件

问题描述

自从我尝试解决将 React Router Link 组件与 Ant Design Tabs 组件一起使用的问题以来已经有一周了。

首先,我基本上遵循 React Router 文档中的嵌套路由部分,根据所需路径创建一个带有路由的 Switch 组件。由于稍后我将不得不在其他组件上重用 Tab 组件,因此我创建了一个基本的自定义 TabMenu 组件,我将一个带有选项卡名称的数组传递到该组件中,以动态映射所需的选项卡。我尝试在 TabPane 组件中为每个映射值包装一个 Link 组件,但它不起作用。

我看到许多解决方案试图解决这个问题,特别是通过在 TabPane 组件的选项卡道具中传递链接或使用带有历史钩子的 onChange Tab 道具推送到所需位置。我尝试了两种方法,但这些解决方案对我来说似乎有点棘手,而且并不适合我。

第一个仅在我单击选项卡文本时才有效,因为链接仅影响选项卡内的文本,而不影响整个选项卡。第二部作品也是如此,但在这种情况下使用历史对我来说似乎并不“传统”。

我真的希望只有 Link 组件有一个基本的解决方案。这是我的代码。谢谢

import { Layout, Menu } from 'antd'
import { Link } from 'react-router-dom'
import { AimOutlined, BookOutlined, DashboardOutlined } from '@ant-design/icons'

const { SubMenu } = Menu
const { Sider } = Layout

const SideMenu = () => {
  return (
    <Sider width={208} style={{
      marginTop: 64, overflow: 'auto',
      zIndex: 1,
      height: '100vh',
      position: 'fixed',
      left: 0
    }}>
      <Menu defaultSelectedKeys={['topMenuItem1']} defaultOpenKeys={['sub1']} className={'side-menu'} mode="inline">
        <Menu.Item key={'topMenuItem1'} icon={<DashboardOutlined/>}>
          <Link to={'/'}> Tableau de bord </Link>
        </Menu.Item>
        <Menu.Item key={'topMenuItem2'} icon={<BookOutlined/>}>
          <Link to={'/missions-catalog'}>Catalogue de missions</Link>
        </Menu.Item>
        <SubMenu key="sub1" icon={<AimOutlined/>} title="Vos missions">
          <Menu.Item key="1">
            <Link to={'/company-referent-missions'}> Missions personnelles </Link>
          </Menu.Item>
          <Menu.Item key="2">
            <Link to={'/company-referent-missions/documents'}>Documents</Link>
          </Menu.Item>
          <Menu.Item key="3">
            <Link to={'/company-referent-missions/favoris'}>Favoris</Link>
          </Menu.Item>
        </SubMenu>
      </Menu>
    </Sider>

  )
}
export default SideMenu
import { Layout, PageHeader } from 'antd'
import { Route, Switch } from 'react-router'
import DashboardEmployeesMissions from '../pages/Dashboard/DashboardEmployeesMissions'
import MyAccount from '../pages/MyAccount'
import CompanyReferentMissions from '../pages/CompanyReferentMissions'
import DashboardHome from '../pages/Dashboard/DashboardHome'
import BreadcrumbNavigation from './BreadcrumbNavigation'
import MissionsCatalogHome from '../pages/MissionsCatalog/MissionsCatalogHome'

const { Content } = Layout

const MainContent = () => {
  return (
    <Content style={{ marginTop: 64, marginLeft: 208, minHeight: '100vh' }} className="main-content">
      <PageHeader title="Tableau de bord" breadcrumb={<BreadcrumbNavigation/>} subTitle="Accueil"/>
      <div className={'main-container'} style={{ backgroundColor: '#F7FBFC', padding: '24px' }}>
        <Switch>
          <Route exact={true} path={'/'}>
            <DashboardHome/>
          </Route>
          <Route path={'/missions-catalog'}>
            <MissionsCatalogHome/>
          </Route>
          <Route path={'/company-referent-missions'}>
            <CompanyReferentMissions/>
          </Route>
          <Route path={'/employees-missions'}>
            <DashboardEmployeesMissions/>
          </Route>
          <Route path={'/my-account'}>
            <MyAccount/>
          </Route>
        </Switch>
      </div>
    </Content>
  )
}
export default MainContent
import React from 'react'
import MissionListItem from '../components/MissionsListItem'
import { Space } from 'antd'
import Title from 'antd/es/typography/Title'
import { Route, Switch, useRouteMatch } from 'react-router-dom'
import MissionCatalogList from './MissionsCatalog/MissionCatalogList'
import { missionApplicationData, missionCatalogData } from '../helpers/DataSeed'
import TabMenu from '../components/TabMenu'

const referentMissionsTabsName = ['Missions', 'Documents', 'Favoris']

const CompanyReferentMissions = () => {
  let { url, path } = useRouteMatch()

  return (
    <Space direction={'vertical'} style={{ width: '100%' }}>
      <Space direction={'vertical'}>
        <Title level={4}>Mission personnelles</Title>
        <TabMenu tabName={referentMissionsTabsName} tabRouterUrl={url}/>
      </Space>
      <Switch>
        <Route exact={true} path={`${path}`}>
          <Space direction={'vertical'} size={'large'} style={{ width: '100%' }}>
            <MissionListItem headerListTitle={<Title level={3}>Candidatures</Title>}
                             dataSource={missionApplicationData()}/>
            <MissionListItem headerListTitle={<Title level={3}>Missions acceptées</Title>}/>
            <MissionListItem headerListTitle={<Title level={3}>Missions terminées</Title>}/>
          </Space>
        </Route>
        <Route path={`${path}/documents`}>
          <Space direction={'vertical'} size={'large'} style={{ width: '100%' }}>
            <MissionListItem headerListTitle={<Title level={3}>Lettres de missions</Title>}/>
            <MissionListItem headerListTitle={<Title level={3}>Attestations de temps passé</Title>}/>
            <MissionListItem headerListTitle={<Title level={3}>Ressources</Title>}/>
          </Space>
        </Route>
        <Route path={`${path}/favoris`}>
          <Space direction={'vertical'} size={'large'} style={{ width: '100%' }}>
            <MissionCatalogList missionsCatalogData={missionCatalogData}/>
          </Space>
        </Route>
      </Switch>
    </Space>
  )
}

export default CompanyReferentMissions
import { Tabs } from 'antd'
import React from 'react'

const { TabPane } = Tabs

const TabMenu = ({ tabName }) => {
  return (
    <Tabs defaultActiveKey={1}>
      {tabName.map((name, index) => {
        return (
          <TabPane key={index + 1} tab={name}/>
        )
      })}
    </Tabs>

  )
}

export default TabMenu

标签: javascriptreactjsreact-routertabsantd

解决方案


如果要根据位置显示活动选项卡,可以执行以下操作

import { Tabs } from 'antd'
import React from 'react'
import { useLocation } from 'react-router-dom';

const { TabPane } = Tabs

const TabMenu = ({ tabName }) => {
  const location = useLocation();

  return (
    <Tabs 
        defaultActiveKey={1} 
        activeKey={tabName.find((name) => name === location.pathname)}
    >
      {tabName.map((name, index) => {
        return (
          <TabPane key={index + 1} tab={name}/>
        )
      })}
    </Tabs>

  )
}

export default TabMenu

如果您想做一些不同的事情,请更详细地描述并提供指向https://codesandbox.io的链接以及一个最小示例


推荐阅读