【问题标题】:Multiple Layouts with React Router v4使用 React Router v4 的多种布局
【发布时间】:2017-04-10 22:33:32
【问题描述】:

我正在努力使用 React Router v4 渲染多个布局。

例如,我希望具有以下路径的页面具有布局 1:

  • 确切路径="/"
  • path="/blog"
  • path="/about"
  • path="/projects"

以及以下路径具有布局 2:

  • path="/blog/:id
  • path="/project/:id

除了 v4 之外,这里有效地回答了什么:Using multiple layouts for react-router components

【问题讨论】:

  • 您需要在这些路由之上创建一个逻辑,以根据路径处理要显示的布局。然后将路线添加到该布局并渲染
  • 如果您可以提交一些代码来演示如何实现这一点,那将非常有帮助。 @ReiDien

标签: reactjs react-router react-router-v4


【解决方案1】:

其他答案均无效,因此我想出了以下解决方案。我在最高级别使用了 render 道具,而不是传统的 component 道具。

它使用layoutPicker 函数根据路径确定布局。如果该路径未分配给布局,则它会返回“错误路线”消息。

import SimpleLayout from './layouts/simple-layout';
import FullLayout from './layouts/full-layout';

var layoutAssignments = {
  '/': FullLayout,
  '/pricing': FullLayout,
  '/signup': SimpleLayout,
  '/login': SimpleLayout
}

var layoutPicker = function(props){
  var Layout = layoutAssignments[props.location.pathname];
  return Layout ? <Layout/> : <pre>bad route</pre>;
};

class Main extends React.Component {
  render(){
    return (
      <Router>
        <Route path="*" render={layoutPicker}/>
      </Router>
    );
  }
}


simple-layout.jsfull-layout.js 遵循以下格式:

class SimpleLayout extends React.Component {
  render(){
    return (
      <div>
        <Route path="/signup" component={SignupPage}/>
        <Route path="/login" component={LoginPage}/>
      </div>
    );
  }
}

【讨论】:

  • 在有人走这条路之前,当你想使用通配符路径时变得很困难,例如'/markets/:id' 我确信有办法解决它,但我无法在几分钟内弄清楚,所以我在下面选择了 Nikolay 的答案
【解决方案2】:

所以,为此你应该使用渲染函数 (https://reacttraining.com/react-router/core/api/Route/render-func)

帮助我的一篇非常好的文章:https://simonsmith.io/reusing-layouts-in-react-router-4/

最后你会使用这样的东西:

<Router>
 <div>
  <DefaultLayout path="/" component={SomeComponent} />
  <PostLayout path="/posts/:post" component={PostComponent} />
 </div>
</Router>

【讨论】:

  • 非常感谢!这些链接非常有用。
【解决方案3】:

我利用您的两种解决方案解决了这个问题:

我的 Routes.js 文件

import BaseWithNav from './layouts/base_with_nav';
import BaseNoNav from './layouts/base_no_nav';

function renderWithLayout(Component, Layout) {
  return <Layout><Component /></Layout>
}

export default () => (
  <Switch>
    {/* Routes with Sidebar Navigation */}
    <Route exact path="/" render={() => renderWithLayout(Home, BaseWithNav)} />

    {/* Routes without Sidebar Navigation */}
    <Route path="/error" render={() => renderWithLayout(AppErrorMsg, BaseNoNav)} />
    <Route path="/*" render={() => renderWithLayout(PageNotFound, BaseNoNav)} />
  </Switch>
)

Base.js(导入路由的地方)

export default class Base extends React.Component {
  render()  {
    return (
      <Provider store={store}>
        <Router>
          <Routes />
        </Router>
      </Provider>
    )
  }
}

布局

BaseWithNav.js

class BaseWithNav extends Component {
  constructor(props) {
    super(props);
  }

  render() {        
    return <div id="base-no-nav">
      <MainNavigation />
      <main>
        {this.props.children}
      </main>
    </div>
  }
}

export default BaseWithNav;

BaseNoNav.js

class BaseNoNav extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    let {classes} = this.props;

    return <div id="base-no-nav">
      <main>
        {this.props.children}
      </main>
    </div>
  }
}

export default BaseNoNav;

我希望这会有所帮助!

【讨论】:

  • 谢谢,这有帮助:)
【解决方案4】:

我知道我回复晚了,但这样做很容易,我希望它对新手有所帮助。 我正在使用 React 4

Layout.js

export default props => (
    <div>
        <NavMenu />
        <Container>
            {props.children}
        </Container>
    </div>
);

LoginLayout.js

export default props => (
    <div>
        <Container>
            {props.children}
        </Container>
    </div>
);

现在我们终于有了我们的应用程序

App.js

function renderWithLoginLayout(Component, Layout) {
    return <LoginLayout><Component /></LoginLayout>
}

function renderWithLayout(Path, Component, Layout) {
    return <Layout><Route path={Path} component={Component} /></Layout>
}


export default () => (
    <Switch>
        <Route exact path='/' render={() => renderWithLayout(this.path, Home, Layout)} />
        <Route path='/counter' render={() => renderWithLayout(this.path, Counter, Layout)} />
        <Route path='/fetch-data/:startDateIndex?' render={() => renderWithLayout(this.path, FetchData, Layout)} />
        <Route path='/login' render={() => renderWithLoginLayout(Login, LoginLayout)} />
    </Switch>
);

【讨论】:

    猜你喜欢
    • 2017-08-09
    • 2016-03-03
    • 2019-01-02
    • 2017-10-17
    • 2018-03-12
    • 1970-01-01
    • 2022-07-04
    • 2017-08-02
    • 1970-01-01
    相关资源
    最近更新 更多