【问题标题】:How to render different Layouts using React?如何使用 React 渲染不同的布局?
【发布时间】:2018-09-24 13:38:48
【问题描述】:

我只想显示此网址的导航栏:/contact/services。而且我不想为/signin 显示导航栏。此刻,这就是我所拥有的:

import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';

import PublicLayout from './components/layouts/PublicLayout';
import SigninLayout from './components/layouts/SigninLayout';

import Main from './components/pages/Main';
import Services from './components/pages/Services';
import Contact from './components/pages/Contact';

class App extends Component {
    render() {
        return (
            <BrowserRouter>
                <div className="App">
                  <Switch>                    
                    <PublicLayout>
                            <Route exact path='/' component={Main} />
                            <Route exact path='/services' component={Services} />
                            <Route exact path='/contact' component={Contact} />
                    </PublicLayout>
                    <SigninLayout>
                            <Route exact path='/signin' component={Signin} />
                    </SigninLayout>
                  </Switch>
                </div>
            </BrowserRouter>
        );
    }
}

export default App;

当我转到/signin url 时,它仍然给我导航栏。那么伙计们——你如何在 React 中为不同的页面呈现不同的布局?请帮忙!

UPD:我的 PublicLayout 代码:

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;

我的 SignInLayout 代码:

import React, { Component } from 'react';

class SigninLayout extends Component {
    state = {

    }

    render() {
        return (
            <div>
                { this.props.children }
            </div>
        );
    }
}

export default SigninLayout;

我的登录组件:

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;

【问题讨论】:

  • 我只是在这方面做得相当糟糕;我在顶层渲染了一个组件,然后根据路由有条件地更改了它的渲染。我有兴趣看到一些更好的解决方案
  • 可以给我们看一下SigninLayout、PublicLayout和Signin组件代码吗?
  • @c-chavez 用代码示例更新了我的问题。谢谢你帮助我。
  • 对于以后的用户,请查看此代码示例codesandbox.io/s/react-router-v5-multiple-layout-forked-y5i1e

标签: javascript reactjs react-router


【解决方案1】:

您可以通过首先使用 switch 语句选择要呈现的布局,然后将应该在该布局内呈现的组件的路由移动到 inside 布局组件来实现这一点。

作为一个非常基本的示例,您的 App 组件可能具有:

<BrowserRouter>
  <div className="App">
    <Switch>
      <Route path="/signin" component={PrivateLayout} />
      <Route path="/" component={PublicLayout} />
    </Switch>
  </div>
</BrowserRouter>

现在在 PublicLayout 中,您可以渲染 Nav 并创建一些新路线,例如

class PublicLayout extends Component {
  render() {
    return (
      <div>
        <h1>Public Place</h1>
        <Navbar items={[]} />
        <Switch>
          <Route exact path='/' component={Main} />
          <Route exact path='/services' component={Services} />
          <Route exact path='/contact' component={Contact} />
        </Switch>
      </div>
    );
  }
}

export default PublicLayout;

...在 PrivateLayout 中,您可以在没有 NavBar 的情况下呈现一组路线,例如

class PrivateLayout extends Component {
  render() {
    return (
      <div>
        <h1>Private Place</h1>
        <Switch>
          <Route exact path="/signin" component={Signin} />
          <Route exact path="/signin/otherpath" component={OtherPrivateComponent} />
        </Switch>
      </div>
    );
  }
}

export default PrivateLayout;

这一切都在一个文件中,您也可以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" component={PrivateLayout} />
          <Route path="/" component={PublicLayout} />
        </Switch>
      </BrowserRouter>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

【讨论】:

  • 是的,我在本地测试过。当你尝试时你看到了什么,这意味着它不起作用?
  • 除了带有导航栏的主页和主页内容之外,它不会呈现任何内容。
  • 这是我的应用程序的样子:prntscr.com/ky4r4w 这是 PublicLayout prntscr.com/ky4rcd
  • 我已经更新了我的答案,提供了一个工作示例的链接,以及一个在单个文件中使用多个组件的代码示例。
  • 我发现了一个错误! 在 App 类中。因此,如果 它将不起作用。但是如果没有 它会。你能解释一下为什么吗?
猜你喜欢
  • 2021-12-28
  • 2019-02-27
  • 2022-08-17
相关资源
最近更新 更多