react-imported-component
Version:
I will import your component, and help to handle it
141 lines (140 loc) • 5.06 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.useLazy = exports.useImported = exports.useLoadable = void 0;
var react_1 = require("react");
var loadable_1 = require("../loadable/loadable");
var marks_1 = require("../loadable/marks");
var pending_1 = require("../loadable/pending");
var detectBackend_1 = require("../utils/detectBackend");
var utils_1 = require("../utils/utils");
var context_1 = require("./context");
function loadLoadable(loadable, callback) {
var upd = function () { return callback({}); };
loadable.loadIfNeeded().then(upd, upd);
}
function updateLoadable(loadable, callback) {
// support HMR
if (process.env.NODE_ENV === 'development') {
var upd_1 = function () { return callback({}); };
loadable._probeChanges().then(function (changed) { return changed && upd_1(); }, upd_1);
}
}
/**
* react hook to wrap `import` with a tracker
* used by {@link useImported}
* @internal
*/
function useLoadable(loadable, options) {
if (options === void 0) { options = {}; }
var UID = (0, react_1.useContext)(context_1.streamContext);
var wasDone = loadable.done;
var _a = (0, react_1.useState)({}), forceUpdate = _a[1];
(0, react_1.useMemo)(function () {
if (options.import !== false) {
if (options.track !== false) {
(0, marks_1.consumeMark)(UID, loadable.mark);
}
if (!wasDone) {
loadLoadable(loadable, forceUpdate);
}
else {
updateLoadable(loadable, forceUpdate);
}
}
return true;
}, [loadable, options.import, options.track]);
if (detectBackend_1.isBackend && !(0, pending_1.isItReady)() && loadable.isLoading()) {
/* tslint:disable:next-line no-console */
console.error('react-imported-component: trying to render a component which is not ready. You should `await whenComponentsReady()`?');
}
// use mark
// retry
var retry = (0, react_1.useCallback)(function () {
if (!loadable) {
return;
}
loadable.reset();
forceUpdate({});
updateLoadable(loadable, forceUpdate);
}, [loadable]);
if (process.env.NODE_ENV !== 'production') {
if (detectBackend_1.isBackend) {
if (!loadable.done) {
/* tslint:disable:next-line no-console */
console.error('react-imported-component: using not resolved loadable. You should `await whenComponentsReady()`.');
}
}
}
return (0, react_1.useMemo)(function () { return ({
loadable: loadable,
retry: retry,
update: forceUpdate,
}); }, [loadable, retry, forceUpdate]);
}
exports.useLoadable = useLoadable;
function useImported(importer, exportPicker, options) {
if (exportPicker === void 0) { exportPicker = utils_1.es6import; }
if (options === void 0) { options = {}; }
var topLoadable = (0, loadable_1.getLoadable)(importer);
var _a = useLoadable(topLoadable, options), loadable = _a.loadable, retry = _a.retry;
var error = loadable.error, done = loadable.done, payload = loadable.payload;
var loading = loadable.isLoading();
return (0, react_1.useMemo)(function () {
if (error) {
return {
error: error,
loadable: loadable,
retry: retry,
};
}
if (done) {
return {
imported: exportPicker(payload),
loadable: loadable,
retry: retry,
};
}
return {
loading: loading,
loadable: loadable,
retry: retry,
};
}, [error, loading, payload, loadable]);
}
exports.useImported = useImported;
/**
* A mix of React.lazy and useImported - uses React.lazy for Component and `useImported` to track the promise
* not "retry"-able
* @see if you need precise control consider {@link useImported}
* @example
* const Component = useLazy(() => import('./MyComponent');
* return <Component /> // throws to SuspenseBoundary if not ready
*/
function useLazy(importer) {
var _a = (0, react_1.useState)(function () {
/* tslint:disable no-shadowed-variable */
var resolve;
var reject;
var promise = new Promise(function (rs, rej) {
resolve = rs;
reject = rej;
});
return {
resolve: resolve,
reject: reject,
lazyComponent: (0, react_1.lazy)(function () { return promise; }),
};
/* tslint:enable */
})[0], resolve = _a.resolve, reject = _a.reject, lazyComponent = _a.lazyComponent;
var _b = useImported(importer), error = _b.error, imported = _b.imported;
(0, react_1.useEffect)(function () {
if (error) {
reject(error);
}
if (imported) {
resolve(imported);
}
}, [error, imported]);
return lazyComponent;
}
exports.useLazy = useLazy;
;