handsome
handsome

Reputation: 2412

Use layout for certain routes in React

I need to maintain a section of my app available for all pages (most of the pages actually) to do that I wrapped the routes in a Layout

<Router>
    <Route path="/login" exact strict component={Login}/>
    <Layout>
        <Route path="/list" exact strict component={List}/>
        <Route path="/settings" exact strict component={Settings}/>
    </Layout>
</Router>

the Layout component looks like this

class Layout extends Component {
    render() {
        return (
            <React.Fragment>
                <div>this box should be visible in all pages using layout</div>
                <div>{this.props.children}</div>
            </React.Fragment>
        )
    }
}

this work perfectly fine. the only poblem is when I go to /login is rendering the Login component and also the Layout component.

I shouldn´t render the Layout if is not for one of the ¨protected¨ routes. is there a way to achieve that without moving the layout inside of the List of Settings component? the reason for this is because the box that´s fixed in all pages makes one API request and there´s no need to do that same API call for /list and /settings. I do it only once.

hope this makes sense to you. thank you!

update: "react-router-dom": "^5.0.1"

Upvotes: 1

Views: 2772

Answers (1)

Dillan Wilding
Dillan Wilding

Reputation: 1111

I've done a fair bit of research on the subject and came up with this. I have it set up in my routes:

import React from 'react'
import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom'
// import PublicRoute, PrivateRoute, Login, Private
<Router>
  <Switch>
    <PublicRoute exact path='/login' component={Login} />
    <PrivateRoute path='/private' component={Private} />
  </Switch>
<Router>

Then in my privateRoute.js:

import React from 'react'
import { Redirect, Route } from 'react-router-dom'
// import useAuth and PrivateLayout
export default ({ componet: Component, ...rest }) => {
  const { token } = useAuth() // wrapper I wrote to handle auth
  if (!token) return <Redirect to='/login' />
  return (
    <Route {...rest} render={props => (
      <PrivateLayout><Component {...props} /></PrivateLayout>
    )} />
  )
}

And my publicRoute.js is similar but without authentication. My layouts are a simple wrapper, all you need to do is include children:

export default ({ children }) => {
  return (
    <>
      <Topbar />
      <Sidebar />
      {children}
    </>
  )

Note: For those who don't know <> is the shorthand for <React.Fragment>.

Upvotes: 4

Related Questions