Как я могу передать имя компонента из объекта другого компонента в Route в 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 в объявлении компонента Route с помощью:

Попытка 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} />
        ))}

но это тоже не работает с ошибкой:

Ошибка: недопустимый тип элемента: ожидалась строка (для встроенных компонентов) или класс/функция (для составных компонентов), а получено: объект.

Проверьте метод рендеринга Router.Consumer.

Я пытался исследовать это, но думаю, что моя неудача связана с тем, что я не знал, как это будет называться в React. Чтение следующего не помогло:

Как я могу превратить ссылочный заголовок из компонента SidebarData в ссылку на компонент в моем маршруте, когда я сопоставляю через SidebarData?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
743
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хороший вопрос, попробуйте это:

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.

Другие вопросы по теме