React Router: как отображать элемент на всех маршрутах, кроме одного?

У меня есть такая структура HTML:

<body>
  <nav>
     <!--navigation elements -->
  </nav>
  <div className='main'>
     <!--other elements -->
  </div>
  <div className='container'></div>
</body>

И маршрутизация определяется следующим образом:

<Router>
  <Fragment>
    <Navbar />
    <Route exact path = "/" component = {Landing} />
    <div className = "container">
       <Alert />
       <Switch>
           <Route exact path = "/register" component = {Register} />
           <Route exact path = "/login" component = {Login} />
           <Route exact path = "/profiles" component = {Profiles} />
       </Switch>
    </div>
  </Fragment>
</Router>

Элемент «контейнер» присутствует на всех маршрутах, однако я не хочу, чтобы он отображался на маршруте «/».

Как я могу остановить рендеринг <div className = "container"> на маршруте "/"? Я хочу, чтобы он отображался на всех других маршрутах, кроме "/".

Решение, которое я нашел, но не хочу использовать, заключается в том, чтобы явно вставить элемент с class = "container" в каждый компонент, который отображается в моем <Switch>. Есть ли способ лучше?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
0
5 000
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Вы должны быть в состоянии достичь того, что вам нужно, с помощью вложенные маршруты и "не совпавший маршрут".

Идея состоит в том, чтобы ввести структуру маршрутизации с помощью вложенных маршрутов, чтобы ограничить рендеринг <div className = "container"> не / маршрутами.

Для этого вы можете извлечь компонент (например, WithContainer), который отображает <Route> для путей; /register, /login и /profiles внутри <div className = "container">. Затем вы должны изменить свой <Switch>, чтобы теперь отображать два маршрута для следующих случаев маршрута;

  1. <Route/>, который отображает компонент Landing при точном совпадении /
  2. <Route/>, который отображает ваш новый компонент WithContainer без определенного маршрута (т. е. любой путь, который точно не соответствует /)

Используя <Switch> таким образом, поведение маршрутизации отображает либо Landing, либо WithContainer (но не оба) в зависимости от первого совпавшего маршрута. Мы используем это поведение, чтобы ограничить отрисовку WithContainer (и, в свою очередь, элемента <div className = "container">) для «не /» маршрутов.

В коде этот подход может быть выражен как:

const WithContainer = () => (
    <div className = "container">
       { /* Wrap routes in container div */ }
       <Route exact path = "/register" component = {Register} />
       <Route exact path = "/login" component = {Login} />
       <Route exact path = "/profiles" component = {Profiles} />
    </div>)

const Main = () => (
  <main> 
    <Switch>
      <Route exact path='/' component = {Landing}/>
      <Route component = { WithContainer } /> {/* No match route */ }
    </Switch>
  </main>
)

Надеюсь, это поможет!

Оно работает! Обратите внимание на особенности: не забудьте реализовать «Switch» внутри «Router» обоих компонентов.

Sth 21.06.2019 12:28

В последней версии React Router вы можете предоставить массив строк для реквизита path, чтобы определенный маршрут отображался при нескольких совпадениях:

<Route path = {['/one', '/two', '/three']} component = {SomeComponent} />

Вот ссылка на соответствующую документацию: https://reacttraining.com/react-router/web/api/Route/путь-строка-строка.

Если вы не хотите создавать отдельный компонент, вы можете просто сделать это. Вам также необходимо сохранить внутренний переключатель, если вы хотите сохранить исходную функциональность.

// parent switch
<Switch>
  <Route exact path = "/" component = {Landing} />
  // start route wrap!!!
  <Route> 
    <div className = "container">
      <Switch>
        <Route exact path = "/register" component = {Register} />
        <Route exact path = "/login" component = {Login} />
        <Route exact path = "/profiles" component = {Profiles} />
      </Switch>
    </div>
  </Route>
 // end route wrap!!!
</Switch>

Вы должны думать о маршрутах как о любых других компонентах пользовательского интерфейса. Вы можете вкладывать их произвольно.

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