13

I am new to ReactJS. I need to have a common header and change title according to the route changes. Do I need to create a header.jsx file and import it? Or else, how can I render the header (common file) with route?

My routing part looks like this:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
import Home from './Home.jsx';
import { Router, Route, Link, browserHistory, IndexRoute  } from 'react-router';

ReactDOM.render((
    <Router history = {browserHistory}>
        <Route path = "/home" component = {Home} />
        <Route path = "/" component = {App}>
        </Route>
    </Router>
));
Jir
  • 2,985
  • 8
  • 44
  • 66
sibi
  • 635
  • 3
  • 8
  • 26
  • You should post the code of what it is your trying to fix. So post the common head component, how it's included in your container/top level component. And how you are doing routing. – agmcleod Jul 21 '16 at 17:06
  • sorry, not fix. yet to do. – sibi Jul 21 '16 at 17:39

3 Answers3

24

This should work:

header.jsx:

class Header extends Component {
  render() {
    return (<div>Your header</div>);
  }
}

first-page.jsx:

class FirstPage extends Component {
  render() {
    return (<div>First page body</div>);
  }
}

second-page.jsx

class SecondPage extends Component {
  render() {
    return (<div>Second page body</div>);
  }
}

app.jsx:

import Header from './header.jsx';

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

web-app.jsx:

import App from './app.jsx';
import FirstPage from './first-page.jsx';
import SecondPage from './second-page.jsx';

ReactDOM.render(
  <Router history = {browserHistory}>
    <Route path = "/" component = {App}>
      <Route path = "/first" component = {FirstPage}>
      <Route path = "/second" component = {SecondPage}>
    </Route>
  </Router>
);
lalkmim
  • 646
  • 4
  • 11
  • Am having multiple jsx file, like Home.jsx, About.jsx. In this case what i need to do. – sibi Jul 22 '16 at 07:43
  • Updated the answer to reflect separated files. – lalkmim Jul 22 '16 at 12:44
  • That's perfect @ lalkmim – sibi Jul 23 '16 at 04:55
  • 1
    In case, if i want to hide component {App} for path "/first", how can we achieve and is it possible to change header title according to route changes. – sibi Jul 23 '16 at 07:56
  • 1
    In that case you'd have to unnest the routes and include the `
    ` component on each of them. But that'd be a bad approach. Everything that is common between routes `/first` and `/second` should be extracted to the `App` component.
    – lalkmim Jul 23 '16 at 14:17
  • what if i want to hide the header in some routes and show in other routes and change the title and show different menus – John Mar 23 '18 at 02:40
  • Do you need browserHistory to make this work? Because I'm following this but it isn't rendering. – Jessica Jun 04 '19 at 14:03
2

try this https://www.npmjs.com/package/react-helmet

import React from "react";
import Helmet from "react-helmet";

export default function Application () {
return (
    <div className="application">
        <Helmet title="My Title" />
        ...
    </div>
);};
  • 2
    Whoever down-voted this, please explain! This plugin looks awesome, it seems well maintained and has a lot of stars ;) – Karl Adler Sep 18 '17 at 06:37
  • 2
    @abimelex - I didn't downvote, but if I understand helmet correctly, it is used to change the "document head" (i.e. the HTML element) not for providing a shared component header as described in the OP's question. – Javid Jamae Jan 10 '18 at 07:54
2

So if you need to display a common header among your routes, there's a couple ways of doing it. One is you can define your header inside its own component. Something simple for example:

import React from 'react';
export default React.createClass({
  render() {
    return <div className='header'><h1>{this.props.title}</h1></div>;
  }
}

Then in your home component, app component, etc. Simply put inside your render(), after importing it at the top of each file.

The other option is to create your own sort of container component, still using the Header component we defined above:

import React from 'react';
export default React.createClass({
  render() {
    return (
      <div className='container'>
        <Header title={this.props.title} />
        {this.props.children}
      </div>
    );
  }
}

Then where you declare your routes:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
import Home from './Home.jsx';
import Container from './Container.jsx';
import { Router, Route, Link, browserHistory, IndexRoute  } from 'react-router';

ReactDOM.render((
    <Router history = {browserHistory}>
        <Route path = "/home" component = {<Container title='home'><Home /></Container>} />
        <Route path = "/" component = {<Container title='app'><App /></Container>}>
        </Route>
    </Router>
));

Admittedly i have not tried that second option. You might have to pass the router as a parameter from the container component down to its use of children component, if you want to do things like router.transitionTo('/path').

It's just an option if you don't want to repeat everywhere.

agmcleod
  • 13,321
  • 13
  • 57
  • 96