usehooks
usehooks copied to clipboard
useLoadMore
Allows creating a 'load more' button that paginates. In theory, one could build an async version of this pretty easily.
import * as R from "ramda";
import { useState } from "react";
/**
* Default to displaying only pageSize items, but allow loadMore.
* @param items Items to return
* @param getId The serialized ID of the item.
* @param pageSize Number of items to display per page.
* @returns [filteredItems, loadMore, hasMore]
*/
function useLoadMore<T>(
items: T[],
getId: ((item: T) => string),
pageSize: number = 5
): [T[], () => void, boolean] {
const maybeNextId = items[pageSize];
const [nextId, setNextId] = useState<string | null>(
maybeNextId ? getId(maybeNextId) : null
);
return [
R.takeWhile(item => getId(item) !== nextId, items),
() => {
if (nextId === null) {
return;
}
const nextIndex = items.findIndex(item => getId(item) === nextId);
const maybeNextPageId = items[nextIndex + pageSize];
setNextId(maybeNextPageId ? getId(maybeNextPageId) : null);
},
!!nextId
];
}
export default useLoadMore;