Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React router global header

I just started learning React, I'm trying to make a SPA blog, which has a global positioned fixed header.

import React from 'react';
import { render } from 'react-dom';
// import other components here

    render((
      <Router history={browserHistory}>
        <Route path="/" component={Home} />
        <Route path="/About" component={About} />
        <Route path="/Contact" component={Contact} />
        <Route path="*" component={Error} />
      </Router>
    ), document.getElementById('app'));

So, each routes has the same header and from my angular background, I would use header outside ui-view.

Its a good practice to import the header component in each individual page component, or can I add the header component on my <Router><myHeader/><otherRoutes/></Router>?

Update:

I was thinking to use something like this:

Routes component, where I define my routes:

class Routes extends React.Component {
    render() {
        return (
            <Router history={browserHistory}>
                <IndexRoute component={Home} />
                <Route path="/studio" component={Studio} />
                <Route path="/work" component={Work} />
                <Route path="*" component={Home} />
            </Router>
        )
    }
}

And then on main Index.js file I would like to render something like:

import Routes from './components/Routes';

render((
   <div>
      <div className="header">header</div>
      <Routes />
   </div>
), document.getElementById('app'));

Can someone explain me? Thanks!

like image 561
Hiero Avatar asked Mar 28 '16 12:03

Hiero


4 Answers

From my experience it can be good to define a layout component for your page, something like...

Layout Component

render() {
    return(
       <div>
          <Header />
             { this.props.children }
             /* anything else you want to appear on every page that uses this layout */
          <Footer />
       </div>
    );
}

You then import layout into each of your page components...

Contact Page Component

render() {
    return (
        <Layout>
           <ContactComponent />
           /* put all you want on this page within the layout component */
        </Layout>
    );
}

And you can leave your routing the same, your route will render the contact page and in turn will render your header.

This way you get control of repetitive stuff that will be on multiple pages, if you need one or two slightly different pages you can just create another layout and use that.

like image 59
Geraint Avatar answered Oct 04 '22 01:10

Geraint


I find this way useful:

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Header from "./components/Header";
import Home from "./components/Home";
import Dashboard from "./components/Dashboard";
import Footer from "./components/Footer";
class App extends Component {
  constructor() {
    super();
    this.state = {
      stuff: stuff;
    };
  }
render() {
 let { stuff } = this.state;
 return (
  <Router> //wrapper for your router, given alias from BrowserRouter
   <div className="App">
    <Header /> //this component will always be visible because it is outside of a specific Route
    <Route exact path="/" component={Home}/>  //at the root path, show this component
    <Route path="/dashboard" component={()=><Dashboard stuff={stuff} />}/>  //at the path '/dashboard', show this other component
    <Footer /> //this is also permanently mounted
   </div>
  </Router>
 );
 }
}
export default App;

credit goes to: David Kerr

like image 40
Mawaheb Avatar answered Oct 04 '22 01:10

Mawaheb


The question is already answered but I'm here to show another approach and say why I prefer that.

I also think that it's a good thing to have a Layout component

function Layout (props) {
  return (
    <div>
      <Header/>
      <div className="content">
        {props.children}
      </div>
    </div>
  );
}

But instead of render it into each route component you can render it just once as a parent for your routes.

return (
  <Router>
    <Layout>
      <Switch>
        <Route path="/about">
          <About/>
        </Route>
        <Route path="/contact">
          <Contact/>
        </Route>
        <Route path="/">
          <Home/>
        </Route>
      </Switch>
    </Layout>
  </Router>
);

This is good because in most cases you will not waste time with the layout and if you have different layouts you only need to work inside the Layout component.

like image 25
Rafael Lebre Avatar answered Oct 03 '22 23:10

Rafael Lebre


For forcefully refresh Header inside routing. use forceRefresh={true}

const Routing = () => {
        return(
            <BrowserRouter forceRefresh={true}>
            <Header/>
            <Switch>
                    <Route exact path="/" component={Home}/>
                    <Route path="/list/:id" component={ListingApi}/>
                    <Route path="/details/:id" component={HotelDetails}/>
                    <Route path="/booking/:hotel_name" component={PlaceBooking}/>
                    <Route path="/viewBooking" component={ViewBooking}/>
                    <Route exact path="/login" component={LoginComponent}/>
                    <Route  path="/signup" component={RegisterComponent}/>
            </Switch>
            <Footer/>
            </BrowserRouter>
        )
    }
like image 22
Aakash Handa Avatar answered Oct 04 '22 01:10

Aakash Handa