Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Lazily Load Code Declaratively in React + Webpack
import React from 'react';
const toPromise = (load) => (new Promise((resolve) => (
load(resolve)
)));
class LazilyLoad extends React.Component {
constructor() {
super(...arguments);
this.state = {
isLoaded: false,
};
}
componentWillMount() {
this.load(this.props);
}
componentWillReceiveProps(next) {
if (next.modules === this.props.modules) return null;
this.load(next);
}
load(props) {
this.setState({
isLoaded: false,
});
const { modules } = props;
const keys = Object.keys(modules);
Promise.all(keys.map((key) => toPromise(modules[key])))
.then((values) => (keys.reduce((agg, key, index) => {
agg[key] = values[index];
return agg;
}, {})))
.then((result) => {
this.setState({ modules: result, isLoaded: true });
});
}
render() {
if (!this.state.isLoaded) return null;
return React.Children.only(this.props.children(this.state.modules));
}
}
LazilyLoad.propTypes = {
children: React.PropTypes.func.isRequired,
};
export const LazilyLoadFactory = (Component, modules) => {
return (props) => (
<LazilyLoad modules={modules}>
{(mods) => <Component {...mods} {...props} />}
</LazilyLoad>
);
};
export const importLazy = (fetch) => (cb) => (
fetch((mod) => cb(mod.default))
);
export default LazilyLoad;
<LazilyLoad modules={{
BuzzHandler: importLazy(require('bundle?lazy&name=buzz!./components/BuzzHandler')),
BuzzMenuHandler: importLazy(require('bundle?lazy&name=buzz!./BuzzMenuHandler/BuzzMenuHandler')),
}}>
{({BuzzHandler, BuzzMenuHandler}) => (
<BuzzHandler>
<BuzzMenuHandler active={BUZZ_MENU_ITEMS.PINNED}>
<BuzzMenu />
</BuzzMenuHandler>
</BuzzHandler>
)}
</LazilyLoad>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment