1 | ;
|
2 |
|
3 | const { useContext } = require('react');
|
4 | const WaterfallRenderContext = require('react-waterfall-render/public/WaterfallRenderContext');
|
5 | const createArgErrorMessageProd = require('../private/createArgErrorMessageProd');
|
6 | const LoadingCacheValue = require('./LoadingCacheValue');
|
7 | const useCache = require('./useCache');
|
8 |
|
9 | /**
|
10 | * A React hook to load a [cache]{@link Cache#store} entry if the
|
11 | * [waterfall render context](https://github.com/jaydenseric/react-waterfall-render#member-waterfallrendercontext)
|
12 | * is populated, i.e. when
|
13 | * [waterfall rendering](https://github.com/jaydenseric/react-waterfall-render#function-waterfallrender)
|
14 | * for either a server side render or to preload components in a browser
|
15 | * environment.
|
16 | * @kind function
|
17 | * @name useWaterfallLoad
|
18 | * @param {CacheKey} cacheKey Cache key.
|
19 | * @param {Loader} load Memoized function that starts the loading.
|
20 | * @returns {boolean} Did loading start. If so, it’s efficient for the component to return `null` since this render will be discarded anyway for a re-render onces the loading ends.
|
21 | * @see [`useAutoLoad`]{@link useAutoLoad}, often used alongside this hook.
|
22 | * @example <caption>Ways to `import`.</caption>
|
23 | * ```js
|
24 | * import { useWaterfallLoad } from 'graphql-react';
|
25 | * ```
|
26 | *
|
27 | * ```js
|
28 | * import useWaterfallLoad from 'graphql-react/public/useWaterfallLoad.js';
|
29 | * ```
|
30 | * @example <caption>Ways to `require`.</caption>
|
31 | * ```js
|
32 | * const { useWaterfallLoad } = require('graphql-react');
|
33 | * ```
|
34 | *
|
35 | * ```js
|
36 | * const useWaterfallLoad = require('graphql-react/public/useWaterfallLoad');
|
37 | * ```
|
38 | */
|
39 | module.exports = function useWaterfallLoad(cacheKey, load) {
|
40 | if (typeof cacheKey !== 'string')
|
41 | throw new TypeError(
|
42 | typeof process === 'object' && process.env.NODE_ENV !== 'production'
|
43 | ? 'Argument 1 `cacheKey` must be a string.'
|
44 | : createArgErrorMessageProd(1)
|
45 | );
|
46 |
|
47 | if (typeof load !== 'function')
|
48 | throw new TypeError(
|
49 | typeof process === 'object' && process.env.NODE_ENV !== 'production'
|
50 | ? 'Argument 2 `load` must be a function.'
|
51 | : createArgErrorMessageProd(2)
|
52 | );
|
53 |
|
54 | const cache = useCache();
|
55 | const declareLoading = useContext(WaterfallRenderContext);
|
56 |
|
57 | if (declareLoading && !(cacheKey in cache.store)) {
|
58 | // Todo: First, check if already loading?
|
59 | const loadingCacheValue = load();
|
60 |
|
61 | if (!(loadingCacheValue instanceof LoadingCacheValue))
|
62 | throw new TypeError(
|
63 | 'Argument 2 `load` must return a `LoadingCacheValue` instance.'
|
64 | );
|
65 |
|
66 | declareLoading(loadingCacheValue.promise);
|
67 |
|
68 | return true;
|
69 | }
|
70 |
|
71 | return false;
|
72 | };
|