У меня есть такая структура 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>
. Есть ли способ лучше?
Вы должны быть в состоянии достичь того, что вам нужно, с помощью вложенные маршруты и "не совпавший маршрут".
Идея состоит в том, чтобы ввести структуру маршрутизации с помощью вложенных маршрутов, чтобы ограничить рендеринг <div className = "container">
не /
маршрутами.
Для этого вы можете извлечь компонент (например, WithContainer
), который отображает <Route>
для путей; /register
, /login
и /profiles
внутри <div className = "container">
. Затем вы должны изменить свой <Switch>
, чтобы теперь отображать два маршрута для следующих случаев маршрута;
<Route/>
, который отображает компонент Landing
при точном совпадении /
<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>
)
Надеюсь, это поможет!
В последней версии 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>
Вы должны думать о маршрутах как о любых других компонентах пользовательского интерфейса. Вы можете вкладывать их произвольно.
Оно работает! Обратите внимание на особенности: не забудьте реализовать «Switch» внутри «Router» обоих компонентов.