UNPKG

@shopify/react-async

Version:

Tools for creating powerful, asynchronously-loaded React components

102 lines (98 loc) 2.65 kB
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 };