Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using multiple layouts for react-router components

Tags:

If I have the following:

<Route path="/" component={Containers.App}>    { /* Routes that use layout 1 */ }   <IndexRoute component={Containers.Home}/>   <Route path="about" component={Containers.About}/>   <Route path="faq" component={Containers.Faq}/>   <Route path="etc" component={Containers.Etc}/>    { /* Routes that use layout 2 */ }   <Route path="products" component={Containers.Products}/>   <Route path="gallery" component={Containers.Gallery}/> </Route> 

How can I make it so that the two sets of routes each use a different layout.

If I only had a single layout then I would put it in App, but in this case where do I define the layout?

To make it even more complicated some of the layout components (eg top nav) are shared between both layout types.

like image 217
SystemicPlural Avatar asked Nov 30 '15 10:11

SystemicPlural


People also ask

Does React allow nested routes?

Nested Routes are a powerful feature. While most people think React Router only routes a user from page to page, it also allows one to exchange specific fragments of the view based on the current route.

How do I use multiple layouts in next JS?

If you need multiple layouts, you can add a property getLayout to your page, allowing you to return a React component for the layout. This allows you to define the layout on a per-page basis. Since we're returning a function, we can have complex nested layouts if desired.


Video Answer


2 Answers

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

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

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

like image 113
SystemicPlural Avatar answered Oct 12 '22 18:10

SystemicPlural


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

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

like image 24
markt Avatar answered Oct 12 '22 17:10

markt