如何将组件的名称从另一个组件的 object 传递到 React Router Dom 中的路由?

How can I pass the component's name from another component's object to Route in React Router Dom?

我正在学习 React,在学习几个教程的同时,我想回去学习如何制作它 D.R.Y 所以给出以下 app.js:

app.js

import React from 'react'
import './App.css'

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'

// Components
import Navbar from './components/Navbar'
import { Home, Reports, Products, Team, Messages, Support } from './pages'

function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" exact component={Home} />
        <Route path="/reports" exact component={Reports} />
        <Route path="/products" exact component={Products} />
        <Route path="/team" exact component={Team} />
        <Route path="/messages" exact component={Messages} />
        <Route path="/support" exact component={Support} />
      </Switch>
    </Router>
  )
}

export default App

我注意到路线也被复制到我用于声明侧边栏的内容 title:

SidebarData.js:

import React from 'react'

import * as FaIcons from 'react-icons/fa'
import * as AiIcons from 'react-icons/ai'
import * as IoIcons from 'react-icons/io'

const SidebarData = [
  { title: 'Home', path: '/', icon: <AiIcons.AiFillHome />, cName: 'nav-text' },
  { title: 'Reports', path: '/reports', icon: <IoIcons.IoIosPaper />, cName: 'nav-text' },
  { title: 'Products', path: '/products', icon: <FaIcons.FaCartPlus />, cName: 'nav-text' },
  { title: 'Team', path: '/team', icon: <IoIcons.IoMdPeople />, cName: 'nav-text' },
  { title: 'Messages', path: '/messages', icon: <FaIcons.FaEnvelopeOpenText />, cName: 'nav-text' },
  { title: 'Support', path: '/support', icon: <IoIcons.IoMdHelpCircle />, cName: 'nav-text' },
]

export default SidebarData

鉴于代码已被复制,我一直在尝试在路由的组件声明中映射组件 SidebarData

尝试 1:

import React from 'react'
import './App.css'

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'

// Components
import Navbar from './components/Navbar'
import SidebarData from './components/SidebarData'
import { Home, Reports, Products, Team, Messages, Support } from './pages'

function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        {SidebarData.map(({ path, title }, i) => (
          <Route key={i} path={path} exact component={title} />
        ))}
      </Switch>
    </Router>
  )
}

export default App

但我收到一个错误,并注意到在调用组件时它不起作用,在 VSC 中我的组件引入了:

import { Home, Reports, Products, Team, Messages, Support } from './pages'

显示为灰色。

尝试 2:

我想也许我可以通过引入组件在 SidebarData 中建立一个参考:

SidebarData.js:

import React from 'react'

import * as FaIcons from 'react-icons/fa'
import * as AiIcons from 'react-icons/ai'
import * as IoIcons from 'react-icons/io'

import { Home, Reports, Products, Team, Messages, Support } from '../pages'

const SidebarData = [
  { title: 'Home', comp: <Home />, path: '/', icon: <AiIcons.AiFillHome />, cName: 'nav-text' },
  {
    title: 'Reports',
    comp: <Reports />,
    path: '/reports',
    icon: <IoIcons.IoIosPaper />,
    cName: 'nav-text',
  },
  {
    title: 'Products',
    comp: <Products />,
    path: '/products',
    icon: <FaIcons.FaCartPlus />,
    cName: 'nav-text',
  },
  { title: 'Team', comp: <Team />, path: '/team', icon: <IoIcons.IoMdPeople />, cName: 'nav-text' },
  {
    title: 'Messages',
    comp: <Messages />,
    path: '/messages',
    icon: <FaIcons.FaEnvelopeOpenText />,
    cName: 'nav-text',
  },
  {
    title: 'Support',
    comp: <Support />,
    path: '/support',
    icon: <IoIcons.IoMdHelpCircle />,
    cName: 'nav-text',
  },
]

export default SidebarData

然后在app.js中更改地图:

{SidebarData.map(({ path, comp }, i) => (
          <Route key={i} path={path} exact component={comp} />
        ))}

但这对以下错误不起作用:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of Router.Consumer.

我试图研究这个,但我认为我的失败是因为不知道在 React 中会调用什么。阅读以下内容无效:

当我通过 SidebarData 映射时,如何将组件 SidebarData 中引用的标题转换为我的 Route 中的组件引用?

好问题,试试这个:

const SidebarData = [
  // ...   
  {
    title: 'Reports',
    comp: Reports,
    path: '/reports',
    icon: <IoIcons.IoIosPaper />,
    cName: 'nav-text',
  },
  {
    title: 'Products',
    comp: Products,
    path: '/products',
    icon: <FaIcons.FaCartPlus />,
    cName: 'nav-text',
  },
  ...

在映射的地方,像这样使用 comp 属性:

{
  SidebarData.map(({ path, comp }, i) => (
    <Route key={i} path={path} exact component={comp} />
  ));
}

而且由于 comp 属性 包含对组件的引用,我认为最好将其大写为 Comp