I want to show Navbar only for this url: /contact
, /services
. And I don't want to show Navbar for /signin
. For this moment this is what I have:
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import PublicLayout from './ponents/layouts/PublicLayout';
import SigninLayout from './ponents/layouts/SigninLayout';
import Main from './ponents/pages/Main';
import Services from './ponents/pages/Services';
import Contact from './ponents/pages/Contact';
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Switch>
<PublicLayout>
<Route exact path='/' ponent={Main} />
<Route exact path='/services' ponent={Services} />
<Route exact path='/contact' ponent={Contact} />
</PublicLayout>
<SigninLayout>
<Route exact path='/signin' ponent={Signin} />
</SigninLayout>
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
When I go to /signin
url it still gives me Navbar. So guys - how do you render different layouts for different pages in React? Please help!
UPD: My PublicLayout Code:
import React, { Component } from 'react';
import Navbar from '../nav/Navbar';
class PublicLayout extends Component {
state = {
items: [
{ id: 1, name: 'Услуги', link: '/services' },
{ id: 2, name: 'Как это работает?', link: '/contacts' },
{ id: 3, name: 'Войти', link: '/signin' },
]
}
render() {
return (
<div>
<Navbar items={ this.state.items } />
{ this.props.children }
</div>
);
}
}
export default PublicLayout;
My SignInLayout code:
import React, { Component } from 'react';
class SigninLayout extends Component {
state = {
}
render() {
return (
<div>
{ this.props.children }
</div>
);
}
}
export default SigninLayout;
My SignIn ponent:
import React, { Component } from 'react';
class Signin extends Component {
state = {
}
render() {
return (
<div>
<h1>Войти</h1>
<form>
<input type="text" placeholder="укажите e-mail" />
<input type="text" placeholder="укажите пароль" />
<button>Войти</button>
</form>
</div>
);
}
}
export default Signin;
I want to show Navbar only for this url: /contact
, /services
. And I don't want to show Navbar for /signin
. For this moment this is what I have:
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import PublicLayout from './ponents/layouts/PublicLayout';
import SigninLayout from './ponents/layouts/SigninLayout';
import Main from './ponents/pages/Main';
import Services from './ponents/pages/Services';
import Contact from './ponents/pages/Contact';
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="App">
<Switch>
<PublicLayout>
<Route exact path='/' ponent={Main} />
<Route exact path='/services' ponent={Services} />
<Route exact path='/contact' ponent={Contact} />
</PublicLayout>
<SigninLayout>
<Route exact path='/signin' ponent={Signin} />
</SigninLayout>
</Switch>
</div>
</BrowserRouter>
);
}
}
export default App;
When I go to /signin
url it still gives me Navbar. So guys - how do you render different layouts for different pages in React? Please help!
UPD: My PublicLayout Code:
import React, { Component } from 'react';
import Navbar from '../nav/Navbar';
class PublicLayout extends Component {
state = {
items: [
{ id: 1, name: 'Услуги', link: '/services' },
{ id: 2, name: 'Как это работает?', link: '/contacts' },
{ id: 3, name: 'Войти', link: '/signin' },
]
}
render() {
return (
<div>
<Navbar items={ this.state.items } />
{ this.props.children }
</div>
);
}
}
export default PublicLayout;
My SignInLayout code:
import React, { Component } from 'react';
class SigninLayout extends Component {
state = {
}
render() {
return (
<div>
{ this.props.children }
</div>
);
}
}
export default SigninLayout;
My SignIn ponent:
import React, { Component } from 'react';
class Signin extends Component {
state = {
}
render() {
return (
<div>
<h1>Войти</h1>
<form>
<input type="text" placeholder="укажите e-mail" />
<input type="text" placeholder="укажите пароль" />
<button>Войти</button>
</form>
</div>
);
}
}
export default Signin;
Share
Improve this question
edited Sep 24, 2018 at 13:49
Nastro
asked Sep 24, 2018 at 13:38
NastroNastro
1,7698 gold badges24 silver badges41 bronze badges
4
- I've only ever done this rather badly; I rendered a ponent at the top level, and then changed it's rendering conditionally based on the route. I'll be interested to see some better solutions – OliverRadini Commented Sep 24, 2018 at 13:41
- Can you show us the SigninLayout, PublicLayout and Signin ponent code? – c-chavez Commented Sep 24, 2018 at 13:43
- @c-chavez updated my question with code samples. Thanks for helping me. – Nastro Commented Sep 24, 2018 at 13:51
- For latter users, pls check this code example codesandbox.io/s/react-router-v5-multiple-layout-forked-y5i1e – unicorn Commented Nov 13, 2021 at 14:40
1 Answer
Reset to default 13You can achieve this by first choosing which layout to render using your switch statement, and then moving the routing for ponents that should be rendered inside that layout to inside the layout ponent.
As a very basic example, your App
ponent could have:
<BrowserRouter>
<div className="App">
<Switch>
<Route path="/signin" ponent={PrivateLayout} />
<Route path="/" ponent={PublicLayout} />
</Switch>
</div>
</BrowserRouter>
Now inside PublicLayout, you can render the Nav and also create some new routes e.g.
class PublicLayout extends Component {
render() {
return (
<div>
<h1>Public Place</h1>
<Navbar items={[]} />
<Switch>
<Route exact path='/' ponent={Main} />
<Route exact path='/services' ponent={Services} />
<Route exact path='/contact' ponent={Contact} />
</Switch>
</div>
);
}
}
export default PublicLayout;
...and in PrivateLayout you can render a set of routes without the NavBar e.g.
class PrivateLayout extends Component {
render() {
return (
<div>
<h1>Private Place</h1>
<Switch>
<Route exact path="/signin" ponent={Signin} />
<Route exact path="/signin/otherpath" ponent={OtherPrivateComponent} />
</Switch>
</div>
);
}
}
export default PrivateLayout;
Here it is all in one file, which you can also see on this codesandbox:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch } from "react-router-dom";
const NavBar = props => <div>Nav Bar</div>;
class PrivateLayout extends Component {
render() {
return (
<div>
<h1>Private</h1>
<Switch>
<Route exact path="/signin" render={() => <h2>Signin</h2>} />
<Route
exact
path="/signin/otherpath"
render={() => <h2>Signin Other</h2>}
/>
</Switch>
</div>
);
}
}
class PublicLayout extends Component {
render() {
return (
<div>
<h1>Public Place</h1>
<NavBar />
<Switch>
<Route exact path="/" render={() => <h2>Main Page</h2>} />
</Switch>
</div>
);
}
}
function App() {
return (
<div className="App">
<BrowserRouter>
<Switch>
<Route path="/signin" ponent={PrivateLayout} />
<Route path="/" ponent={PublicLayout} />
</Switch>
</BrowserRouter>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);