Skip to content Skip to sidebar Skip to footer

Using Multiple Layouts For React-router Components

If I have the following: { /* Routes that use layout 1 */ }

Solution 1:

You can use routes without a path to define containers that are not defined by the url:

<Routepath="/"component={Containers.App}>

  { /* Routes that use layout 1 */ }
  <Routecomponent={Containers.Layout1}><IndexRoutecomponent={Containers.Home}/><Routepath="about"component={Containers.About}/><Routepath="faq"component={Containers.Faq}/><Routepath="etc"component={Containers.Etc}/></Route><Routecomponent={Containers.Layout2}>
    { /* Routes that use layout 2 */ }
    <Routepath="products"component={Containers.Products}/><Routepath="gallery"component={Containers.Gallery}/></Route></Route>

The layout components can then import additional components such as the top nav

Solution 2:

Route's path property has accepted an array of strings for a while now. See https://github.com/ReactTraining/react-router/pull/5889/commits/4b79b968389a5bda6141ac83c7118fba9c25ff05

Simplified to match the question routes, but I have working multiple layouts essentially like this (using react-router 5):

<App><Switch><Routepath={["/products", "/gallery"]}><LayoutTwo><Switch><Routepath="/products"component={Products} /><Routepath="/gallery"component={Gallery} /></Switch></LayoutTwo></Route>
    {/* Layout 1 is last because it is used for the root "/" and will be greedy */}
    <Routepath={["/about", "/faq", "/etc", "/"]}><LayoutOne><Switch><IndexRoutecomponent={Home} /><Routepath="/about"component={About} /><Routepath="/faq"component={Faq} /><Routepath="/etc"component={Etc} /></Switch></LayoutOne></Route></Switch></App>

This solution prevents re-mounting the layouts on route changes, which can break transitions, etc.

Solution 3:

Here's a great way to use multiple layouts with different React components.

In your router you can use:

<Routerhistory={browserHistory}><Routecomponent={MainLayout}><Routepath="/"component={Home} /><Routepath="/about"component={About} /></Route><Routecomponent={EmptyLayout}><Routepath="/sign-in"component={SignIn} /></Route><Routepath="*"component={NotFound}/></Router>

enter image description here

Source: https://sergiotapia.me/different-layouts-with-react-router-71c553dbe01d

Solution 4:

Pintouch, I was able to get this working with the following example:

Layout1:

importReactfrom'react'constLayout1 = (props) => (
    <div><h1>Layout 1</h1>
        {props.children}
    </div>
)

exportdefaultLayout1

Layout2:

importReactfrom'react'constLayout2 = (props) => (
    <div><h1>Layout 2</h1>
        {props.children}
    </div>
)

exportdefaultLayout2

Layout Container:

importReactfrom'react'constLayoutContainer = (props) => (
    <div>
                {props.children}
    </div>
)

exportdefaultLayoutContainer

Routes:

importReactfrom'react';
import { Router, Route, IndexRoute, hashHistory } from'react-router';

importLayoutContainerfrom'./LayoutContainer'importLayout1from'./Layout1'importLayout2from'./Layout2'importContactManagerViewfrom'./ContactManagerView'importCallerIdViewfrom'./CallerIdView'importNotFoundfrom'./NotFound'

<Router history={hashHistory}>
    <Routepath="/"component={LayoutContainer}><Routecomponent={Layout1}><IndexRoutecomponent={DashboardView}/><Routepath='Contacts'component={ContactManagerView}/></Route><Routecomponent={Layout2}><Routepath='CallerId'component={CallerIdView}/></Route><Routecomponent={Layout}><Routepath='*'component={NotFound}/></Route></Route>
</Router>

Solution 5:

You could create a function RouteWithLayout that renders the <Route> wrapped within the layout:

constRouteWithLayout = ({ component: Component, layout: Layout, ...rest }) => (
  <Route {...rest} render={props => (
    <Layout><Component {...props} /></Layout>
  )} />
)

constMainLayout = props => (
  <div><h1>Main</h1>
    {props.children}
  </div>
)

constAltLayout = props => (
  <div><h1>Alt</h1>
    {props.children}
  </div>
)

constFoo = () => (
  <p>Foo</p>
)

constBar = () => (
  <p>Bar</p>
)

constApp = () => (
  <div><Switch><RouteWithLayoutexactpath="/foo"layout={MainLayout}component={Foo} /><RouteWithLayoutexactpath="/bar"layout={AltLayout}component={Bar} /></Switch></div>
)

Post a Comment for "Using Multiple Layouts For React-router Components"