Skip to content

Instantly share code, notes, and snippets.

@gabemeola
Created April 16, 2017 21:53
Show Gist options
  • Save gabemeola/c42047219e92563f2f7ff33da66e3d98 to your computer and use it in GitHub Desktop.
Save gabemeola/c42047219e92563f2f7ff33da66e3d98 to your computer and use it in GitHub Desktop.
Lazyloading React components using React Router and Webpack Code Module Splitting
import React, { Component, PropTypes } from 'react';
import { LoadingSplash, LoadingSpinner } from 'components/Injectables';
export default class LazyLoad extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
error: '',
};
this.componentToRender = null;
}
componentDidMount() {
this.load();
}
componentWillUnmount() {
this.componentToRender = null;
}
load = async () => {
const { render, renderName } = this.props;
try {
const toRender = await render;
this.componentToRender = toRender[renderName];
this.setState({
loading: false,
error: '',
})
} catch (err) {
this.setState({
loading: true,
error: err,
})
}
}
render() {
const { render, key, renderName, loadingType, ...props } = this.props;
return this.state.loading === true
? loadingType === 'splash'
? <LoadingSplash/>
: <LoadingSpinner/>
: React.createElement(this.componentToRender, props);
}
}
LazyLoad.propTypes = {
render: PropTypes.instanceOf(Promise).isRequired,
key: PropTypes.any.isRequired,
renderName: PropTypes.string,
loadingType: PropTypes.oneOf(['spinner', 'splash'])
};
LazyLoad.defaultProps = {
renderName: 'default',
loadingType: 'splash'
};
// Framework Imports
import React from 'react';
import { HashRouter, Route, Switch, Redirect } from 'react-router-dom';
import LazyLoad from './LazyLoad';
import FormComplete from 'components/FormSummary/FormComplete';
import HeaderContainer from 'containers/Header/HeaderContainer';
export default function getRoutes(getState) {
const isFormStarted = () => getState().form.metadata.app.formStarted;
function setIndexRoute() {
return isFormStarted() === true ? '/form' : '/build';
}
return(
<HashRouter>
<section className="mainWrapper" id="sidebar-outer-container">
<HeaderContainer/>
<div id="page-content-wrapper">
<Switch>
<Route exact from="/" render={() =>
<Redirect to={setIndexRoute()}/>
}/>
<Route path="/advisor" render={(props) =>
<LazyLoad render={import('components/Advisor/AdvisorComponent')} {...props}
key={props.match.url}/>
}/>
<Route path="/dashboard" render={(props) =>
<LazyLoad render={import('containers/Dashboard/DashboardContainer')} {...props}
key={props.match.url}/>
}/>
<Route path="/build" render={(props) =>
isFormStarted() !== true
? <LazyLoad render={import('containers/Build/BuildContainer')} {...props} key={props.match.url}/>
: <Redirect to="/form"/>
}/>
<Route path="/form" render={(props) =>
isFormStarted() === true
? <LazyLoad render={import('containers/Form/FormContainer')} {...props} key={props.match.url}/>
: <Redirect to="/build"/>
}/>
<Route path="/summary" render={(props) =>
<LazyLoad render={import('components/FormSummary/FormSummary')} {...props} key={props.match.url}/>
}/>
<Route path="/complete" component={FormComplete} />
</Switch>
</div>
</section>
</HashRouter>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment