反应:对不同的路线使用不同的布局

时间:2019-02-21 21:30:28

标签: reactjs

我遇到一个有点奇怪的问题,尝试将组件拆分为使用两种不同的布局。我有2种布局:PublicLayoutLayout,其中我的App.js的路线定义如下:

render() {
    return (
      <ApolloProvider client={client}>
        <Layout>
          <Route path="/articles" component={ArticlesIndex} exact={true} />
          <Route
             path="/articles/create"
             component={ArticlesCreate}
             exact={true}
          />
          <Route
            path="/articles/edit/:id"
            component={ArticlesEdit}
            exact={true}
          />
        </Layout>
        <PublicLayout>
          <Route exact path="/" component={Home} exact={true} />
          <Route 
          path="/articles/view/:id"
          component={ArticlesView}
          exact={true}
          />
        </PublicLayout>
      </ApolloProvider>
     );
   }

Layout的外观如下:

<div className="container">
    <Grid fluid>
      <Row>
        <Col sm={12}>
          {this.props.children}
        </Col>
      </Row>
    </Grid>
  </div>

我在PublicLayout标记内的所有路线/组件均按预期方式呈现和运行。但是,使用我的Layout组件的所有路线/组件均按预期方式渲染,但是在其下方渲染了PublicLayout。我猜测PublicLayout被包含在这些页面上,因为它在Layout部分之后没有任何限定条件出现。如何克服这个问题,只在其包含的路线上渲染PublicLayout

感谢所有帮助。

更新:我通过使用以下内容解决了我的问题,该内容使我可以按路线任意定义每个路线的布局:

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


export default class App extends Component {
  displayName = App.name;

  render() {
    return (
      <ApolloProvider client={client}>
          <Route 
            path="/articles" 
            render={(props) => renderWithLayout(ArticlesIndex, Layout, props)} 
            exact={true} 
            />
          <Route
             path="/articles/create"
             render={(props) => renderWithLayout(ArticlesCreate, Layout, props)}
             exact={true}
          />
          <Route
            path="/articles/edit/:id"
            render={(props) => renderWithLayout(ArticlesEdit, Layout, props)}
            exact={true}
          />
          <Route 
            path="/" 
            render={(props) => renderWithLayout(Home, PublicLayout, props)} 
            exact={true} 
            />
          <Route 
              path="/articles/view/:id"
              render={(props) => renderWithLayout(ArticlesView, PublicLayout, props)}
              exact={true}
              />
      </ApolloProvider>
     );
   }
}

2 个答案:

答案 0 :(得分:1)

使用条件渲染。假设loggedIn是用来跟踪用户是否已通过身份验证的内容。

render() {
    return {
      <ApolloProvider client={client}>
        { loggedIn ? (
        <Layout>
          <Route path="/articles" component={ArticlesIndex} exact={true} />
          <Route
             path="/articles/create"
             component={ArticlesCreate}
             exact={true}
          />
          <Route
            path="/articles/edit/:id"
            component={ArticlesEdit}
            exact={true}
          />
        </Layout>
        ) : (
        <PublicLayout>
          <Route exact path="/" component={Home} exact={true} />
          <Route 
          path="/articles/view/:id"
          component={ArticlesView}
          exact={true}
          />
        </PublicLayout>
       )}
      </ApolloProvider>
     );
   }

有关其他示例和解决方案https://reactjs.org/docs/conditional-rendering.html

答案 1 :(得分:0)

除非我在这里没有遗漏任何重要的细节,否则看起来react确实在执行渲染函数告诉它的操作。那里没有条件渲染,因此您将始终拥有Layout和PublicLayout。

通过在它们周围添加条件来解决。您可以简单地提取成两个不同的函数,然后根据想要驱动该输出的任何条件渲染一个或另一个。