diff options
Diffstat (limited to 'packages/website/ts/lazy_component.tsx')
-rw-r--r-- | packages/website/ts/lazy_component.tsx | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/packages/website/ts/lazy_component.tsx b/packages/website/ts/lazy_component.tsx new file mode 100644 index 000000000..7052b7be6 --- /dev/null +++ b/packages/website/ts/lazy_component.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import * as _ from 'lodash'; + +interface LazyComponentProps { + reactComponentPromise: Promise<React.ComponentClass<any>>; + reactComponentProps: any; +} + +interface LazyComponentState { + component?: React.ComponentClass<any>; +} + +/** + * This component is used for rendering components that are lazily loaded from other chunks. + * Source: https://reacttraining.com/react-router/web/guides/code-splitting + */ +export class LazyComponent extends React.Component<LazyComponentProps, LazyComponentState> { + constructor(props: LazyComponentProps) { + super(props); + this.state = { + component: undefined, + }; + } + public componentWillMount() { + this.loadComponentFireAndForgetAsync(this.props); + } + public componentWillReceiveProps(nextProps: LazyComponentProps) { + if (nextProps.reactComponentPromise !== this.props.reactComponentPromise) { + this.loadComponentFireAndForgetAsync(nextProps); + } + } + public render() { + return _.isUndefined(this.state.component) ? + null : + React.createElement(this.state.component, this.props.reactComponentProps); + } + private async loadComponentFireAndForgetAsync(props: LazyComponentProps) { + const component = await props.reactComponentPromise; + this.setState({ + component, + }); + } +} + +/** + * [createLazyComponent description] + * @param componentName name of exported component + * @param lazyImport lambda returning module promise + * we pass a lambda because we only want to require a module if it's used + * @example `const LazyPortal = createLazyComponent('Portal', () => System.import<any>('ts/containers/portal'));`` + */ +export const createLazyComponent = (componentName: string, lazyImport: () => Promise<any>) => { + return (props: any) => { + const reactComponentPromise = (async (): Promise<React.ComponentClass<any>> => { + const mod = await lazyImport(); + const component = mod[componentName]; + return component; + })(); + return ( + <LazyComponent + reactComponentPromise={reactComponentPromise} + reactComponentProps={props} + /> + ); + }; +}; |