@shopify/react-async
Version:
Tools for creating powerful, asynchronously-loaded React components
94 lines (89 loc) • 2.49 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var reactEffect = require('@shopify/react-effect');
var reactHooks = require('@shopify/react-hooks');
var assets = require('./context/assets.js');
function usePreload(...args) {
const [preloadable, options = {}] = args;
return preloadable.usePreload(options);
}
function usePrefetch(...args) {
const [prefetchable, options = {}] = args;
return prefetchable.usePrefetch(options);
}
function useKeepFresh(...args) {
const [keepFreshable, options = {}] = args;
return keepFreshable.useKeepFresh(options);
}
function useAsync(resolver, {
assets,
scripts = assets,
styles = assets,
immediate = true
} = {}) {
const [value, setValue] = React.useState(() => immediate || typeof window !== 'undefined' ? resolver.resolved : null);
const mounted = reactHooks.useMountedRef();
const load = React.useCallback(async () => {
if (value != null) {
return value;
}
try {
const resolved = await resolver.resolve();
if (mounted.current) {
// It's important to use the function form of setValue here.
// Resolved is going to be a function in most cases, since it's
// a React component. If you do not set it using the function form,
// React treats the component as the function that returns state,
// so it sets state with the result of manually calling the component
// (so, usually JSX).
setValue(() => resolved);
}
return resolved;
} catch (error) {
if (mounted.current) {
setValue(error);
}
return error;
}
}, [mounted, resolver, value]);
const {
id
} = resolver;
useAsyncAsset(id, {
scripts,
styles
});
return value instanceof Error ? {
id,
resolved: null,
error: value,
loading: false,
load
} : {
id,
resolved: value,
error: null,
loading: value == null,
load
};
}
function useAsyncAsset(id, {
scripts,
styles
} = {}) {
const async = React.useContext(assets.AsyncAssetContext);
reactEffect.useServerEffect(() => {
if (async && id) {
async.markAsUsed(id, {
scripts,
styles
});
}
}, async === null || async === void 0 ? void 0 : async.effect);
}
exports.useAsync = useAsync;
exports.useAsyncAsset = useAsyncAsset;
exports.useKeepFresh = useKeepFresh;
exports.usePrefetch = usePrefetch;
exports.usePreload = usePreload;