UNPKG

react-ketting

Version:
100 lines 3.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.usePagedCollection = void 0; const react_1 = require("react"); const use_read_resource_1 = require("./use-read-resource"); /** * The usePagedCollection hook works similar to useCollection, but has the * ability to load in additional pages of items. * * For this to work, the API needs to expose a "next" link on the collection. * As long as there are "next" links, more pages can be loaded in. * * Additional items from collection pages will be appended to "items", * allowing frontends to build 'infinite scroll' features. * * Example call: * * <pre> * const { * loading, * error, * items, * hasNextPage, * loadNextPage * } = usePagedResource<Article>(resource); * </pre> * * The resource may be passed as a Resource object, a Promise<Resource>, or a * uri string. * * Returned properties: * * * loading - will be true every time we're going to the server and fetch a * a new page. * * error - Will be null or an error object. * * items - Will contain an array of resources, each typed Resource<T> where * T is the passed generic argument. * * hasNextPage - Will be true if the server has another page. * * loadNextPage - Loads the next page, and appends the new items to the * items array. */ function usePagedCollection(resourceLike, options) { var _a; const rel = (options === null || options === void 0 ? void 0 : options.rel) || 'item'; const [items, setItems] = (0, react_1.useState)([]); const [currentCollectionResource, setCurrentCollectionResource] = (0, react_1.useState)(resourceLike); // This is the 'base collection' const bc = (0, use_read_resource_1.useReadResource)(resourceLike, { refreshOnStale: options === null || options === void 0 ? void 0 : options.refreshOnStale, // This header will be included on the first, uncached fetch. // This may be helpful to the server and instruct it to embed // all collection members in that initial fetch. initialGetRequestHeaders: { Prefer: 'transclude=' + rel, } }); // This is the 'current collection const cc = (0, use_read_resource_1.useReadResource)(currentCollectionResource, { refreshOnStale: options === null || options === void 0 ? void 0 : options.refreshOnStale, // This header will be included on the first, uncached fetch. // This may be helpful to the server and instruct it to embed // all collection members in that initial fetch. initialGetRequestHeaders: { Prefer: 'transclude=' + rel, } }); (0, react_1.useEffect)(() => { // We're loading a new 'base collection', so lets clear any items we got setItems([]); // Set the 'current' page back to the first page in the collection. setCurrentCollectionResource(resourceLike); }, [bc.resource]); (0, react_1.useEffect)(() => { if (cc.resourceState) { // This effect gets triggered when we get data for a new page. // When we do, append the items to our array. setItems([ ...items, ...cc.resourceState.followAll(rel) ]); } }, [(_a = cc.resourceState) === null || _a === void 0 ? void 0 : _a.uri]); const hasNextPage = !cc.loading && cc.resourceState && cc.resourceState.links.has('next'); const loadNextPage = () => { if (!hasNextPage) { console.warn('loadNextPage was called, but there was no next page'); return; } setCurrentCollectionResource(cc.resourceState.follow('next')); }; return { loading: cc.loading, error: cc.error, items, hasNextPage, loadNextPage, }; } exports.usePagedCollection = usePagedCollection; //# sourceMappingURL=use-paged-collection.js.map