Last active
September 8, 2016 18:22
-
-
Save goldhand/88fe8fca823fceb7130d7362e327bd51 to your computer and use it in GitHub Desktop.
React content delivery model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react'; | |
import {connect} from 'react-redux'; | |
import {bindActionCreators} from 'redux'; | |
import {withRouter} from 'react-router'; | |
import * as actions from 'actions/contentActions'; | |
import {getContent} from 'reducers/content'; | |
/** | |
* connectPage is a high order component that requests page data, if not already available | |
* depending on the route url | |
* | |
* @param {Class} ComponentClass - the component to be decorated | |
* @returns {Class} - the decorated component | |
*/ | |
const connectContent = (ComponentClass) => { | |
@withRouter | |
@connect( | |
(state, ownProps) => { | |
const slug = ownProps.params.slug || 'home'; | |
return { | |
content: getContent(state.content, slug), | |
slug, | |
}; | |
}, | |
dispatch => (bindActionCreators(actions, dispatch)), | |
) | |
class ConnectContent extends Component { | |
static propTypes = { | |
content: PropTypes.object.isRequired, | |
fetchPage: PropTypes.func.isRequired, | |
slug: PropTypes.string.isRequired, | |
} | |
componentWillMount() { | |
const {fetchPage, slug} = this.props; | |
fetchPage(slug); | |
} | |
componentWillReceiveProps(newProps) { | |
const {fetchPage, slug} = this.props; | |
if (slug !== newProps.slug) { | |
fetchPage(newProps.slug); | |
} | |
} | |
render = () => <ComponentClass {...this.props} /> | |
} | |
return ConnectContent; | |
}; | |
export default connectContent; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component, PropTypes} from 'react'; | |
import connectContent from 'components/ConnectContent'; | |
// import container components | |
// import ExampleApp from 'components/ExampleApp'; | |
// map imports to strings so they can be selected with data | |
const sectionTypes = { | |
// example: ExampleApp, | |
}; | |
@connectContent | |
export default class PageApp extends Component { | |
static propTypes = { | |
content: PropTypes.object.isRequired, | |
} | |
/** | |
* Dynamically build sections using fetched content data | |
* Section component options are imported manually and mapped. | |
* The section.component is a string that matches the desired component type | |
* | |
* @returns {ReactComponent[]} - array of rendered react components | |
*/ | |
buildSections() { | |
const {content: {sections}} = this.props; | |
// TODO: show loading or fetch from cache | |
if (!sections) return null; | |
return Object.keys(sections).map(id => { | |
return React.createElement( | |
sectionTypes[sections[id].type], | |
{ | |
...sections[id].content, | |
key: `section-${id}`, | |
}, | |
); | |
}); | |
} | |
render() { | |
return ( | |
<div> | |
{this.buildSections()} | |
</div> | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AppShell from 'components/AppShell'; // common accross all views | |
import Page from 'components/PageApp'; | |
export default { | |
getChildRoutes(location, callback) { | |
callback(null, [ | |
{ | |
path: '/', | |
component: AppShell, | |
indexRoute: {component: Page}, | |
getChildRoutes(loc, cb) { | |
cb(null, [ | |
{ | |
path: '/(:slug)', | |
component: Page, | |
}, | |
]); | |
}, | |
}, | |
]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment