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);
}
componentDidMount() {
this._isMounted = true;
}
componentWillReceiveProps(next) {
if (next.modules === this.props.modules) return null;
this.load(next);
}
componentWillUnmount() {
this._isMounted = false;
}
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) => {
if (!this._isMounted) return null;
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>
@dxtr026

This comment has been minimized.

Copy link

dxtr026 commented Aug 31, 2016

Liked the approach, we are also doing something of this kind. But this just gave me idea to organize my code better.

@TheLarkInn

This comment has been minimized.

Copy link

TheLarkInn commented Oct 5, 2016

Awesome job.

@leefsmp

This comment has been minimized.

Copy link

leefsmp commented Mar 5, 2017

Niiiiice

@sujoy18

This comment has been minimized.

Copy link

sujoy18 commented Jul 13, 2017

I am facing a problem by following this approach. When container component update state and trigger re-render, the child component which is lazily loaded lost its input element focus. E.g. I have a child textbox component and I loaded it lazily in my container component. onChange of textbox component I am updating state of my container component and at that moment the focus is lost from text box. Any help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.