Last active
May 26, 2017 16:40
-
-
Save selfcontained/808273e2d7fb570cd853919ba966fbf6 to your computer and use it in GitHub Desktop.
Lazy Load React component pattern
This file contains 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 from 'react' | |
class LazyLoad extends React.Component { | |
constructor () { | |
super(...arguments) | |
this.state = { | |
isLoaded: false | |
} | |
} | |
componentDidMount () { | |
this._isMounted = true | |
this.load() | |
} | |
componentDidUpdate (previous) { | |
const shouldLoad = !!Object.keys(this.props.modules).filter((key) => { | |
return this.props.modules[key] !== previous.modules[key] | |
}).length | |
if (shouldLoad) { | |
this.load() | |
} | |
} | |
componentWillUnmount () { | |
this._isMounted = false | |
} | |
load () { | |
this.setState({ | |
isLoaded: false | |
}) | |
const { modules } = this.props | |
const keys = Object.keys(modules) | |
Promise.all(keys.map((key) => 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 () { | |
let {EmptyState} = this.props | |
if (!this.state.isLoaded) return EmptyState ? <EmptyState {...this.props} /> : null | |
return React.Children.only(this.props.children(this.state.modules)) | |
} | |
} | |
export const LazyLoadFactory = (Component, modules, EmptyState) => { | |
return (props) => ( | |
<LazyLoad modules={modules} EmptyState={EmptyState}> | |
{(mods) => <Component {...mods} {...props} />} | |
</LazyLoad> | |
) | |
} | |
export default LazyLoad |
This file contains 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 from 'react' | |
import {LazyLoadFactory} from 'components/lazy-load/' | |
class LazyLoadedThingy extends React.PureComponent { | |
render () { | |
let {Component} = this.props | |
return ( | |
<Component.default {...this.props} /> | |
) | |
} | |
} | |
function Placeholder (props) { | |
return ( | |
<div className='loading'>Loading...</div> | |
) | |
} | |
export default LazyLoadFactory(LazyLoadedThingy, { | |
// path to the component we want to load lazily and keep in it's own bundle | |
Component: () => System.import(/* webpackChunkName: "thingy" */'./thingy') | |
}, Placeholder) |
This file contains 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 from 'react' | |
class Thingy extends React.PureComponent { | |
render () { | |
return ( | |
<div> | |
<p>Do some really heavy things in here and include all sorts of things we don't want loaded by default</p> | |
</div> | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment