8

Basically I want to include a header, sidebar and footer to each page. I've currently got the above mentioned on each individual page with react router clicking through to each of them. I want to down size my code and have one main template that allows each main section of each page to be unique with the header, footer and sidebar nav in place. What's the best place to add this? Tried in the App.js and index, but doesn't seem to like that.

I'm using antd as my main framework.

Thanks in advance!

 ReactDOM.render((
   <div>
     <Layout>
       <Sider>
         <SideMenu />
       </Sider>
       <Layout>
         <Header />
         <Content style={{ margin: '0 16px' }}>
           <div className='appWrap'>
             <BrowserRouter>
               <LocaleProvider locale={enUS}>
                 <App />
               </LocaleProvider>
             </BrowserRouter>
             <Footer />
           </div>
         </Content>
       </Layout>
     </Layout>
   </div>
), document.getElementById('root'));

Something along the lines of this. I want the template to load around the main App.js I've seen using router to create separate templates won't save me on code as it's what I pretty much have already.

scunliffe
  • 62,582
  • 25
  • 126
  • 161
Sadie
  • 95
  • 1
  • 1
  • 6
  • 1
    Post some code that you have attempted to get to work – spirift Oct 10 '17 at 09:40
  • Just updated. :) – Sadie Oct 10 '17 at 09:47
  • I think you are pretty much there with that layout, you have some elements and components that are not being closed off in the correct order. I guess your `App` component contains your routes? What is the error you get at the moment? – spirift Oct 10 '17 at 10:04
  • If i have that code in the index.js it complains about defining routes. My router is in app.js at the moment, that's correct. – Sadie Oct 10 '17 at 10:07
  • You should not use or withRouter() outside a ▶ 20 stack frames were collapsed. ./src/index.js D:/TFS/Websites/Main/software/src/index.js:9 6 | import enUS from 'antd/lib/locale-provider/en_US'; 7 | import Header from './Components/Header/Header'; 8 | > 9 | ReactDOM.render(( 10 |
    11 |
    12 |
    – Sadie Oct 10 '17 at 10:08
  • Sure you don't have any `Route` components in `Layout` `Sider` `SideMenu` `Header` or `Content`? Try moving the `BrowserRouter` to wrap everything. – spirift Oct 10 '17 at 10:21
  • Move it to where? I'm a little confused, sorry! – Sadie Oct 10 '17 at 10:28

3 Answers3

5

I'm currently using a similar approach by creating a custom component that passes the props to the Route component:

routes.jsx:

import React, { Fragment } from 'react';
import {
  BrowserRouter as Router,
  Switch
} from 'react-router-dom';
import LayoutDefault from './views/layouts/LayoutDefault';
import Startpage from './views/Startpage';

const Routes = () => (
  <Router>

    <Switch>
      <LayoutDefault exact path="/dashboard" component={Startpage} />
      // ... more routes
    </Switch>

  </Router>
);

export default Routes;

And LayoutDefault.jsx

import React, { Fragment } from 'react';
import { Route } from 'react-router-dom';
import LoggedinMenu from 'modules/Menu/LoggedinMenu';

const LayoutDefault = (props) => (
  <Fragment>
    <LoggedinMenu />
    <Route {...props} />
  </Fragment>
);

export default LayoutDefault;
Jonas Sandstedt
  • 1,160
  • 11
  • 12
2

I would wrap the template code into it's own components. Here is a simple demo of using the template for every page. You can also choose the leave the router unchanged and using the template component in each page directly. Hope it helps.

Template.jsx:

class Template extends React.Component {
  render() {
    return (
      <Layout style={{ minHeight: '100vh' }}>
        <Layout.Sider>Sider</Layout.Sider>
        <Layout>
          <Layout.Header>Header</Layout.Header>
          <Layout.Content>
            {this.props.children}
          </Layout.Content>
          <Layout.Footer>Footer</Layout.Footer>
        </Layout>
      </Layout>
    );
  }
}

index.jsx

ReactDOM.render(
    <Template>
        <BrowserRouter>
            <LocaleProvider locale={enUS}>            
                <Route path='/' component={Root} />
                <Route path='/about' component={About} />
                <Route path='/profile' component={Profile} />
            </LocaleProvider>
        </BrowserRouter>
    </Template>,
    document.getElementById('root')
);
yihuaf
  • 363
  • 3
  • 9
1

Something like this. Make sure everything is inside the BrowserRouter component.

ReactDOM.render(
    <BrowserRouter>
        <LocaleProvider locale={enUS}>
            <Header />
            <Route path='/' component={Root} />
            <Route path='/about' component={About} />
            <Route path='/profile' component={Profile} />
            <Footer />
        </LocaleProvider>
    </BrowserRouter>,
    document.getElementById('root')
);
spirift
  • 2,994
  • 1
  • 13
  • 18