usehooks icon indicating copy to clipboard operation
usehooks copied to clipboard

useLoadMore

Open macalinao opened this issue 5 years ago • 0 comments

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;

macalinao avatar Feb 26 '19 19:02 macalinao