Skip to content

Instantly share code, notes, and snippets.

@davesherratt
Forked from koistya/DefaultLayout.jsx
Created January 26, 2016 21:02
Show Gist options
  • Save davesherratt/e5383d111e05c5b68fe4 to your computer and use it in GitHub Desktop.
Save davesherratt/e5383d111e05c5b68fe4 to your computer and use it in GitHub Desktop.
React.js (ReactJS) Page and Layout components. For a complete sample visit https://github.com/kriasoft/react-starter-kit and http://reactjs.kriasoft.com (demo)

Page is URL-bound React component. For example, the /questions/votes URL on StackOverflow is bound to the <Questions sort="votes" /> component.

Layout is a wrapper for Page component, which itself can be wrapped in other layouts (for more complex pages). Layout usually contains header, footer, navigation, sidebar and other similar components as well as {this.props.children}.

It's is better to define the type of the layout to use on a Page lavel as opposed to somwhere else (e.g. in routing). Also at a page level you want to define page title either as a property or a state variable which is then passed to the layout component (or asynchronously via Flux's action creator).

With the layout approach # 1 (PageOne.jsx) the page can be rendered like this:

var React = require('react');
var copyProperties = require('react/lib/copyProperties');

/**
 * Check if Page component has a layout property; and if yes, wrap the page
 * into the specified layout, then mount to document.body.
 */
function render(page) {
  var child, props = {};
  while (page.defaultProps.layout) {
    child = page(props, child);
    copyProperties(props, page.defaultProps);
    page = page.defaultProps.layout;
  }
  React.renderComponent(page(props, child), document.body);
}

render(require('./pages/profile.jsx'));
/**
* Page layout, reused across multiple Page components
* @jsx React.DOM
*/
var React = require('react');
var ExecutionEnvironment = require('react/lib/ExecutionEnvironment');
var Navigation = require('../components/Navigation.jsx');
var DefaultLayout = React.createClass({
propTypes: {
title: React.PropTypes.string
},
render() {
return (
<div>
<div className="l-header">
<h1>Company Name</h1>
<Navigation />
</dv>
<div className="l-content">
<h1>{this.props.title}</h1>
{this.props.children}
</div>
<div className="l-footer">
<p>Copyright (c) 2014 Company Name</p>
</div>
</div>
);
},
componentDidMount() {
if (ExecutionEnvironment.canUseDOM) {
document.title = this.props.title;
}
}
});
module.exports = DefaultLayout;
/**
* Layout approach #1
* @jsx React.DOM
*/
var React = require('react');
var DefaultLayout = require('../layouts/DefaultLayout.jsx');
var PageOne = React.createClass({
getDefaultProps() {
return {
title: 'Page One',
layout: DefaultLayout
};
},
render() {
return (
<div>
<p>The page's content...</p>
<p>goes here.</p>
</div>
);
}
});
/**
* Layout approach #2
* @jsx React.DOM
*/
var React = require('react');
var DefaultLayout = require('../layouts/DefaultLayout.jsx');
var PageOne = React.createClass({
getDefaultProps() {
return {
title: 'Page Two'
};
},
render() {
return (
<DefaultLayout title={this.props.title}>
<p>The page's content...</p>
<p>goes here.</p>
</DefaultLayout>
);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment