UNPKG

5.06 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.useLazy = exports.useImported = exports.useLoadable = void 0;
4var react_1 = require("react");
5var loadable_1 = require("../loadable/loadable");
6var marks_1 = require("../loadable/marks");
7var pending_1 = require("../loadable/pending");
8var detectBackend_1 = require("../utils/detectBackend");
9var utils_1 = require("../utils/utils");
10var context_1 = require("./context");
11function loadLoadable(loadable, callback) {
12 var upd = function () { return callback({}); };
13 loadable.loadIfNeeded().then(upd, upd);
14}
15function updateLoadable(loadable, callback) {
16 // support HMR
17 if (process.env.NODE_ENV === 'development') {
18 var upd_1 = function () { return callback({}); };
19 loadable._probeChanges().then(function (changed) { return changed && upd_1(); }, upd_1);
20 }
21}
22/**
23 * react hook to wrap `import` with a tracker
24 * used by {@link useImported}
25 * @internal
26 */
27function useLoadable(loadable, options) {
28 if (options === void 0) { options = {}; }
29 var UID = (0, react_1.useContext)(context_1.streamContext);
30 var wasDone = loadable.done;
31 var _a = (0, react_1.useState)({}), forceUpdate = _a[1];
32 (0, react_1.useMemo)(function () {
33 if (options.import !== false) {
34 if (options.track !== false) {
35 (0, marks_1.consumeMark)(UID, loadable.mark);
36 }
37 if (!wasDone) {
38 loadLoadable(loadable, forceUpdate);
39 }
40 else {
41 updateLoadable(loadable, forceUpdate);
42 }
43 }
44 return true;
45 }, [loadable, options.import, options.track]);
46 if (detectBackend_1.isBackend && !(0, pending_1.isItReady)() && loadable.isLoading()) {
47 /* tslint:disable:next-line no-console */
48 console.error('react-imported-component: trying to render a component which is not ready. You should `await whenComponentsReady()`?');
49 }
50 // use mark
51 // retry
52 var retry = (0, react_1.useCallback)(function () {
53 if (!loadable) {
54 return;
55 }
56 loadable.reset();
57 forceUpdate({});
58 updateLoadable(loadable, forceUpdate);
59 }, [loadable]);
60 if (process.env.NODE_ENV !== 'production') {
61 if (detectBackend_1.isBackend) {
62 if (!loadable.done) {
63 /* tslint:disable:next-line no-console */
64 console.error('react-imported-component: using not resolved loadable. You should `await whenComponentsReady()`.');
65 }
66 }
67 }
68 return (0, react_1.useMemo)(function () { return ({
69 loadable: loadable,
70 retry: retry,
71 update: forceUpdate,
72 }); }, [loadable, retry, forceUpdate]);
73}
74exports.useLoadable = useLoadable;
75function useImported(importer, exportPicker, options) {
76 if (exportPicker === void 0) { exportPicker = utils_1.es6import; }
77 if (options === void 0) { options = {}; }
78 var topLoadable = (0, loadable_1.getLoadable)(importer);
79 var _a = useLoadable(topLoadable, options), loadable = _a.loadable, retry = _a.retry;
80 var error = loadable.error, done = loadable.done, payload = loadable.payload;
81 var loading = loadable.isLoading();
82 return (0, react_1.useMemo)(function () {
83 if (error) {
84 return {
85 error: error,
86 loadable: loadable,
87 retry: retry,
88 };
89 }
90 if (done) {
91 return {
92 imported: exportPicker(payload),
93 loadable: loadable,
94 retry: retry,
95 };
96 }
97 return {
98 loading: loading,
99 loadable: loadable,
100 retry: retry,
101 };
102 }, [error, loading, payload, loadable]);
103}
104exports.useImported = useImported;
105/**
106 * A mix of React.lazy and useImported - uses React.lazy for Component and `useImported` to track the promise
107 * not "retry"-able
108 * @see if you need precise control consider {@link useImported}
109 * @example
110 * const Component = useLazy(() => import('./MyComponent');
111 * return <Component /> // throws to SuspenseBoundary if not ready
112 */
113function useLazy(importer) {
114 var _a = (0, react_1.useState)(function () {
115 /* tslint:disable no-shadowed-variable */
116 var resolve;
117 var reject;
118 var promise = new Promise(function (rs, rej) {
119 resolve = rs;
120 reject = rej;
121 });
122 return {
123 resolve: resolve,
124 reject: reject,
125 lazyComponent: (0, react_1.lazy)(function () { return promise; }),
126 };
127 /* tslint:enable */
128 })[0], resolve = _a.resolve, reject = _a.reject, lazyComponent = _a.lazyComponent;
129 var _b = useImported(importer), error = _b.error, imported = _b.imported;
130 (0, react_1.useEffect)(function () {
131 if (error) {
132 reject(error);
133 }
134 if (imported) {
135 resolve(imported);
136 }
137 }, [error, imported]);
138 return lazyComponent;
139}
140exports.useLazy = useLazy;