UNPKG

3.16 kBJavaScriptView Raw
1/**
2 * asAsync - a HOC for async loading components.
3 *
4 * Usage:
5 *
6 * const AsyncDialog = asAsync({
7 * load: () => import('Dialog').then(result => result.default),
8 * });
9 *
10 * React.render(domElement, <AsyncDialog asyncPlaceholder={ () => <Spinner/> } { ...dialogProps } />);
11 *
12 * Note the `asyncPlaceholder` prop will be respected when rendering the async component and it hasn't
13 * been loaded yet.
14 */
15import { __assign, __extends, __rest } from "tslib";
16import * as React from 'react';
17/**
18 * If possible, use a WeakMap to maintain a cache of loaded components.
19 * This can be used to synchronously render components that have already been loaded,
20 * rather than having to wait for at least one async tick.
21 */
22var _syncModuleCache = typeof WeakMap !== 'undefined'
23 ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
24 new WeakMap()
25 : undefined;
26/**
27 * Produces a component which internally loads the target component before first mount.
28 * The component passes all props through to the loaded component.
29 *
30 * This overload accepts a module with a default export for the component.
31 */
32export function asAsync(options) {
33 var Async = /** @class */ (function (_super) {
34 __extends(Async, _super);
35 function Async() {
36 var _this = _super !== null && _super.apply(this, arguments) || this;
37 _this.state = {
38 Component: _syncModuleCache ? _syncModuleCache.get(options.load) : undefined,
39 };
40 return _this;
41 }
42 Async.prototype.render = function () {
43 // Typescript issue: the rest can't be pulled without the any cast, as TypeScript fails with rest on generics.
44 // eslint-disable-next-line @typescript-eslint/no-explicit-any
45 var _a = this.props, forwardedRef = _a.forwardedRef, Placeholder = _a.asyncPlaceholder, rest = __rest(_a, ["forwardedRef", "asyncPlaceholder"]);
46 var Component = this.state.Component;
47 return Component ? (React.createElement(Component, __assign(__assign({}, rest), { ref: forwardedRef }))) : Placeholder ? (React.createElement(Placeholder, null)) : null;
48 };
49 Async.prototype.componentDidMount = function () {
50 var _this = this;
51 var Component = this.state.Component;
52 if (!Component) {
53 options
54 .load()
55 .then(function (LoadedComponent) {
56 if (LoadedComponent) {
57 // Cache component for future reference.
58 _syncModuleCache && _syncModuleCache.set(options.load, LoadedComponent);
59 // Set state.
60 _this.setState({
61 Component: LoadedComponent,
62 }, options.onLoad);
63 }
64 })
65 .catch(options.onError);
66 }
67 };
68 return Async;
69 }(React.Component));
70 return React.forwardRef(function (props, ref) { return React.createElement(Async, __assign({}, props, { forwardedRef: ref })); });
71}
72//# sourceMappingURL=asAsync.js.map
\No newline at end of file