Skip to content

Instantly share code, notes, and snippets.

@wilsoncook
Last active January 25, 2021 03:19
Show Gist options
  • Save wilsoncook/3f6f3e8184887c13528b9ed2e8c0587e to your computer and use it in GitHub Desktop.
Save wilsoncook/3f6f3e8184887c13528b9ed2e8c0587e to your computer and use it in GitHub Desktop.
Allow define React Component with async dependencies
/**
* Allow define React Component with async dependencies
* @param defineClass Return a new class that depends on deps
* @param asyncDeps Define what the class depends on
*/
export function makeDepsComponent<T extends React.ComponentType<any>, D>(
defineClass: (deps: D) => T,
asyncDeps: () => Promise<D>,
) {
return makeLazyComponent(async () => defineClass(await asyncDeps()));
}
/**
* 生成一个异步加载组件
* @param factory 异步加载函数
* @param loading? loading态dom
*/
export function makeLazyComponent<T extends React.ComponentType<any>>(
factory: () => Promise<{ default: T } | T>,
options: {
loading?: React.ReactNode;
} = {},
) {
const { loading } = options;
// 注:proxyref使用小写,避免"React does not recognize the `proxyRef` prop on a DOM element"
const LazyComponent = class extends React.PureComponent<{ proxyref: any }> {
state: { Component?: React.ComponentType<any> } = {};
componentDidMount() {
factory().then((mod: any) => this.setState({ Component: mod.default || mod }));
}
render() {
const { Component } = this.state;
if (!Component) return loading || null; // loading态
return <Component {...this.props} ref={this.props.proxyref} />;
}
};
return (React.forwardRef((props, ref) => <LazyComponent {...props} proxyref={ref} />) as unknown) as T;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment