首页 文章

使用React Router v4的多个布局

提问于
浏览
7

我正试着用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

3 回答

  • 9

    所以,为此你应该使用渲染功能(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>
    
  • 0

    其他答案都没有用,所以我提出了以下解决方案 . 我使用了 render 道具而不是最高级别的传统 component 道具 .

    它使用 layoutPicker 函数根据路径确定布局 . 如果该路径未分配给布局,则返回"bad route"消息 .

    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>
        );
      }
    }
    
  • 5

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

    My Routes.js file

    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;
    

    我希望这有帮助!

相关问题