ReactJS Header and Footer

64,444

I suggest that you don't render the Router component twice (I haven't checked but you probably can't).

So, how the Router component works :

  • You give the router an history (via the history props), here you use the browserHistory from the same library wich is fine.
  • Then you define all the existing routes for your application using the Route component with a path, and the component to load if the browser url match this path property.

Now, in your case I suggest you to do something like that :

app.js

import {Router, Route, browserHistory} from 'react-router'
import Layout from './components/Layout'
// Import here all the required components used by the router such as SignIn, Register, ...

render(
    <Layout>
        <Router history={browserHistory}>
            <Route path="/" component={RT_Footer}>
            <Route path="/About Us" component={About}/>
            <Route path="/Terms & Conditions" component={TC}/>
            <Route path="/Register" component={Register}/>
           // Add as many Route components as needed
        </Router>
    </Layout>,
    document.getElementById('react-anchor')

Then your layout file should look like this :

layout.js

import Header from './Header'
import Footer from './Footer'
import React, {Component} from 'react'

class Layout extends Component {
    render() {
        return (
            <div>
                <Header />
                {this.props.children}
                <Footer />
            </div>
        )
    }
}

And in your Header and Footer component, render whatever you want, to provide link to load the requested component you can use from react-router or some other way the library offer (see their documentation)

Edit :

Careful about route Path, like "Terms & Conditions" is probably not a valid path

Share:
64,444
Roy
Author by

Roy

Updated on February 19, 2020

Comments

  • Roy
    Roy about 4 years

    I am trying to create a Layout component which would render the Header and Footer. So that I can later on use the Layout like

    <Layout> ... </Layout>
    

    I have used Routing in the Header and Footer, obviously. To do this, I need to use

    <Router history...
     <Route path...
    

    When I do this one after the other(for header and footer: though I feel that this is wrong) in my layout.js. It works. The header and footer are shown in the browser. However, they don't work properly. On refresh the footer vanishes and sometimes both, the header and the footer. I strongly believe that rendering Router one after the other is the reason for this malfunctioning, but I can't figure out the correct approach. Moreover, I don't want to use the following snippets

    header.js

    import React from 'react';
    import {Link} from 'react-router'
    import {Navbar, NavItem} from 'react-materialize';
    
    export default React.createClass({
      render(){
        return (
        <div>
          <Navbar brand='logo' right>
            <NavItem><Link to="/Home" activeClassName="active">Home</Link></NavItem>
            <NavItem><Link to="/Sign-In" activeClassName="active">Sign In</Link></NavItem>
            <NavItem><Link to="/Register" activeClassName="active">Register</Link></NavItem>
          </Navbar>
          {this.props.children}
        </div>
        )
      }
    })
    

    footer.js

    import React, {Component} from 'react';
    import {Link} from 'react-router'
    import {Footer} from 'react-materialize';
    import '../../resource/template.css'
    
    
    class RT_Footer extends Component{
      render(){
        return (
        <div>
          {this.props.children}
          <Footer copyrights="&copy; 2015 Copyright Text"
              moreLinks={
                <Link className="grey-text text-lighten-4 right" href="#!">More Links</Link>
              }
              links={
                <ul>
                  <li><Link to="/About Us" className="grey-text text-lighten-3">About Us</Link></li>
                  <li><Link to="/Terms & Conditions" className="grey-text text-lighten-3">Terms & Conditions</Link></li>
                  <li><Link to="/Help" className="grey-text text-lighten-3">Help</Link></li>
                  <li><Link to="/Contact Us" className="grey-text text-lighten-3">Contact Us</Link></li>
                </ul>
              }
              className='example'
          >
            <h5 className="white-text">Footer Content</h5>
            <p className="grey-text text-lighten-4">You can use rows and columns here to organize your footer content.</p>
          </Footer>
        </div>
        );
      }
    }
    export default RT_Footer;
    

    layout.js

    import {Router, Route, browserHistory} from 'react-router'
    
    class Layout extends Component {
      render(){
        return (
          <div>
          <span>
            <Router history={browserHistory}>
              <Route path="/" component={Header}>
               <Route path="/Home" component={Home}/>
               <Route path="/Sign-In" component={SignIn}/>
               <Route path="/Register" component={Register}/>
              </Route>
            </Router>
          </span>
          <span>
            <Router history={browserHistory}>
              <Route path="/" component={RT_Footer}>
               <Route path="/About Us" component={About}/>
               <Route path="/Terms & Conditions" component={TC}/>
               <Route path="/Register" component={Register}/>
              </Route>
            </Router>
          </span>
          </div>
        );
      }
    }
    export default Layout;
    

    Then I simply rendered Layout in index.js

  • Roy
    Roy over 7 years
    But its still not working in spite of using <Router history={browserHistory}> <Route path="/" component={Header}> <Route path="/Home" component={Home}/> <Route path="/SignIn" component={SignIn}/> <Route path="/Register" component={Register}/> </Route> <Route path="/" component={Footer}> <Route path="/AboutUs" component={AboutUs}/> </Route> </Router>
  • Varg
    Varg over 5 years
    @Quentin, I tried to use this answer and received the following error: Uncaught Error: You should not use <Link> outside a <Router> Why it happened? The code is the same, only with <Link> inside <Header />
  • JDNickell
    JDNickell almost 4 years
    Any component including <Link> would need to be nested within <Router>. Maybe try <Router><Layout><Route><Route>...
  • Swaprks
    Swaprks almost 4 years
    @Quentin this is helpful. Worked for me. I am facing one issue here. I have to show the header and footer only when the user logs in. I am able to access the token {this.props.children} but its not accessible in the header or footer. Can you help with the please?