Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional rendering with React Router

Tags:

react-router

I'd like to render some routes with a nav at the top, while rendering other routes (like a sign-up / sign-in page) without any nav.

render example with react router

For the setup with the nav, I have:

const App = () => (
  <Router>
    <div>
      <Nav />
      <div>
        <Route exact path="/" component={Home} />
        <Route path="/account" component={Account} />
        <Route path="/news" component={News} />
      </div>
      <Footer />
    </div>
  </Router>
);

I'm trying to find the best way of handling this with React Router (seems like it would have to handled with some type of conditional maybe? - "if my current route matches any one of these routes, then render like so else render this.").

Thanks!

like image 323
hidace Avatar asked Oct 20 '17 03:10

hidace


3 Answers

You have at least two possibilities:

  1. Use Route "path" property to test the route and render the component. Path property accepts path.to.regexp expressions.
  2. Wrap your component with withRouter method and inside Nav test if the route matches and render null otherwise.

First answer:

const App = () => (
  <Router>
    <div>
      <Route path="/(?!signin|signup)" component={Nav}/>
      <div>
        <Route exact path="/" component={Home} />
        <Route path="/account" component={Account} />
        <Route path="/news" component={News} />
      </div>
      <Footer />
    </div>
  </Router>
);

Second answer:

import { withRouter } from 'react-router'
const NavWithRouter = withRouter(Nav);

const App = () => (
  <Router>
    <div>
      <NavWithRouter/>
      <div>
        <Route exact path="/" component={Home} />
        <Route path="/account" component={Account} />
        <Route path="/news" component={News} />
      </div>
      <Footer />
    </div>
  </Router>
);
like image 81
ChrisR Avatar answered Oct 21 '22 20:10

ChrisR


<Route path={`foo/(A|B|C)`} component={() => (<Baz {...props}/>)} />

Where A,B,C are the different routes like foo/A.

like image 35
shinzou Avatar answered Oct 21 '22 20:10

shinzou


I usually use two different Layout pages. And within the Layout pages, have a router for the content.

My code will look like this:

<Router>
  <Route path="/login" component={AuthLayout} />
  <Route path="/logout" component={AuthLayout} />
  <Route path="/some/path" component={Layout} />
</Router>

Within each Layout, there will be the usual header / footer / navbars and then another set of routes.

<div className="auth-layout">
  <header className="auth-layout__header"></header>
  <main className="auth-layout__content">
    <Switch>
      <Route path="/login" component={Login} />
      <Route path="/logout" component={Logout} />
    </Switch>
  </main>
</div>

In this way, I have a direct mapping from requirements to code. In my code, there are much more differences between the two layouts.

like image 29
vijayst Avatar answered Oct 21 '22 19:10

vijayst