Last active
January 25, 2021 03:19
-
-
Save wilsoncook/3f6f3e8184887c13528b9ed2e8c0587e to your computer and use it in GitHub Desktop.
Allow define React Component with async dependencies
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
/** | |
* 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