@shopify/react-async
Version:
Tools for creating powerful, asynchronously-loaded React components
102 lines (98 loc) • 2.65 kB
JavaScript
import React, { useEffect } from 'react';
import { createResolver } from '@shopify/async';
import { useIdleCallback } from '@shopify/react-idle';
import { useAsync } from './hooks.mjs';
import { AssetTiming } from './types.mjs';
function createAsyncContext({
id,
load
}) {
const resolver = createResolver({
id,
load
});
const Context = /*#__PURE__*/React.createContext(null);
// Just like a "normal" value returned from `createContext`, rendering
// the value itself is not supported. This component is just a placeholder
// to provide a more useful error.
function Root() {
throw new Error('Do not attempt to render the result of calling `createAsyncContext()` directly. Render its `.Provider` component instead.');
}
function Provider(props) {
const {
load,
resolved
} = useAsync(resolver, {
assets: AssetTiming.Immediate
});
useEffect(() => {
load();
}, [load]);
return /*#__PURE__*/React.createElement(Context.Provider, Object.assign({
value: resolved
}, props));
}
function Consumer(props) {
return /*#__PURE__*/React.createElement(Context.Consumer, props);
}
function usePreload() {
return useAsync(resolver, {
assets: AssetTiming.NextPage
}).load;
}
function Preload() {
const preload = usePreload();
useIdleCallback(preload);
return null;
}
function Prefetch() {
const preload = usePreload();
useEffect(() => {
preload();
}, [preload]);
return null;
}
const FinalComponent = Root;
Reflect.defineProperty(FinalComponent, 'resolver', {
value: resolver,
writable: false
});
Reflect.defineProperty(FinalComponent, 'Provider', {
value: Provider,
writable: false
});
Reflect.defineProperty(FinalComponent, 'Consumer', {
value: Consumer,
writable: false
});
Reflect.defineProperty(FinalComponent, 'Context', {
value: Context,
writable: false
});
Reflect.defineProperty(FinalComponent, 'Preload', {
value: Preload,
writable: false
});
Reflect.defineProperty(FinalComponent, 'Prefetch', {
value: Prefetch,
writable: false
});
Reflect.defineProperty(FinalComponent, 'KeepFresh', {
value: Preload,
writable: false
});
Reflect.defineProperty(FinalComponent, 'usePreload', {
value: usePreload,
writable: false
});
Reflect.defineProperty(FinalComponent, 'usePrefetch', {
value: usePreload,
writable: false
});
Reflect.defineProperty(FinalComponent, 'useKeepFresh', {
value: usePreload,
writable: false
});
return FinalComponent;
}
export { createAsyncContext };