最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to render different Layouts using React? - Stack Overflow

programmeradmin4浏览0评论

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
Add a ment  | 

1 Answer 1

Reset to default 13

You 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);
发布评论

评论列表(0)

  1. 暂无评论