npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-easy-infinite-scroll-hook

v2.1.4

Published

A react hook for creating simple, fast and lightweight components with infinite scrolling in any direction, supporting both windowed and scrollable elements.

Downloads

8,501

Readme

react-easy-infinite-scroll-hook

Version Badge NPM license Stars Test GZipped size PRs Welcome Downloads NPM total downloads

A hook that will save you from endless scrolling problems! Infinite scrolling that really works and is very easy to integrate! This hook allows you to create simple, lightweight components with infinite scrolling in all directions, supporting both windowed and scrollable elements. Works with any third-party libraries, you just need to specify the correct container for the ref object. Check out the demo for some examples.

Features

  • Universal - Ability to use all types of HTML elements or any UI or virtualized libraries
  • 📦 Support for all loading directions - You can infinitely scroll a component in any direction or in all directions at once (up, down, left, right)
  • 📏 No need to specify heights - No need to pass the dimensions of the component, scrollbar or element
  • 💬 Support for "chat history" - Reverse mode includes
  • 👫 Cross-browser - Works out-of-the-box for most browsers, regardless of version.
  • ⚙️ Matches native API - Intuitive to use
  • 🛠 Written in TypeScript - It'll fit right into your existing TypeScript project
  • 📲 Mobile-friendly - Supports mobile devices and touch screens.
  • Fully unit tested - 100% test coverage
  • 🌳 Tree-shakeable - Only include the parts you use
  • 💥 Lightweight - Around ~2.4kB
  • 💨 No dependencies

Install

  # with npm
  npm install --save react-easy-infinite-scroll-hook
  # with yarn
  yarn add react-easy-infinite-scroll-hook

Usage

You can create infinite scrolling in any direction and in any pair, for example: up-down, down-right, etc. and even all at once.

Simple Example

Edit useInfiniteScroll

import useInfiniteScroll from 'react-easy-infinite-scroll-hook';

const InfiniteListComponent = ({ isLoading, items, canLoadMore, next }) => {
  // TypeScript example:
  // const ref = useInfiniteScroll<YourElemntType>(...props);
  const ref = useInfiniteScroll({
    // Function to fetch more items
    next,
    // The number of items loaded if you use the "Y-scroll" axis ("up" and "down")
    // if you are using the "X-scroll" axis ("left" and "right") use "columnCount" instead
    // you can also use "rowCount" and "columnCount" if you use "Y-scroll" and "X-scroll" at the same time 
    rowCount: items.length,
    // Whether there are more items to load
    // if marked "true" in the specified direction, it will try to load more items if the threshold is reached
    // support for all directions "up", "down", "left", "right", both individually and in all directions at the same time
    hasMore: { down: canLoadMore },
  });

  return (
    <div
      ref={ref}
      style={{
        height: 500,
        overflowY: 'auto',
      }}
    >
      {items.map((item) => (
        <div key={item.key}>{item.value}</div>
      ))}
      {isLoading && <div>Loading...</div>}
    </div>
  );
};

Virtualized Example (react-virtualized)

This hook supports all react-virtualized components (Collection, Grid, MultiGrid, List, Masonry, Table). Check out the demo for more examples.

Try it live:

| Component | Description | Link | | :-------: | -------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | List | Virtualized List component with infinite scroll | Edit useInfiniteScroll | | Grid | Virtualized Grid component with infinite scroll down and right | Edit useInfiniteScroll |

import useInfiniteScroll from 'react-easy-infinite-scroll-hook';
import { List } from 'react-virtualized';

const VirtualizedInfiniteListComponent = ({ isLoading, items, canLoadMore, next }) => {
  const ref = useInfiniteScroll({
    next,
    rowCount: items.length,
    hasMore: { down: canLoadMore },
  });

  return (
    <div>
      <List
        ref={ref}
        width={500}
        height={500}
        rowHeight={60}
        rowCount={items.length}
        rowRenderer={({ key, index, style }) => {
          const item = data[index];

          return (
            <div key={key} style={style}>
              {item}
            </div>
          );
        }}
      />
      {isLoading && <div>Loading...</div>}
    </div>
  );
};

API

After initialization, this hook returns a React ref object, which you must pass to your element ref.

Props

| Name | Required | Description | Type | Default Value | | --------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | :-----------: | | next | Yes | A callback when more items are requested by the user. Receives a single parameter specifying the direction to load e.g. (direction) => Promise<void> | Function | | | hasMore | Yes | Whether there are more items to load. If marked true in the specified direction, it will try to load more items if the threshold is reached. Expect object with directions to load { up: false, down: false, left: false, right: false } | object | | | rowCount | Condition | Number of items in a vertical list (scroll axis Y). Required if you are using vertical scroll. | number | | | columnCount | Condition | Number of items in a horizontal list (scroll axis X). Required if you are using horizontal scroll. | number | | | onScroll | | The callback is called when the container is scrolled: ({ clientHeight: number, scrollHeight: number, scrollTop: number, clientWidth: number, scrollWidth: number, scrollLeft: number }) => void | Function | | | initialScroll | | The initial scroll position of the element, which is applied after the ref has been initialized | object | | | reverse | | The direction of the scroll axis is used to create scrolling in the opposite direction, for example when using the CSS style flex-direction: 'row-reverse' | object | | | scrollThreshold | | The threshold at which the next function is called. It can be specified in pixels from the scrollbar value, for example '200px' and as a percentage of the container size from 0.1 to 1 (1 is 100%) | number or string | 1 | | windowScroll | | When set to true, uses a window as the scroll element. If you are using a scroll window, then anything you pass to the ref will be ignored | boolean | false |

Supported Browsers

react-easy-infinite-scroll-hook aims to support all evergreen browsers and recent mobile browsers for iOS and Android. IE 9+ is also supported.

If you find a browser-specific problem, please report it.

Friends

FAQ

Can I use it with other virtualized or components libraries?

Yes you can! To use it with other libraries you must specify the correct DOM element for the ref object.

Can I use it with flex-direction: 'column-reverse'?

Yes, just pass reverse: { column: true } to props for flex-direction: 'column-reverse' or reverse: { row: true } for flex-direction: 'row-reverse'.

How to use it with react-virtualized MultiGrid component?

MultiGrid is a complex component with a lot of scrollable containers, and to use it you must specify the correct container for the ref object:

import React, { useCallback } from 'react';
import useInfiniteScroll from 'react-easy-infinite-scroll-hook';
import { MultiGrid } from 'react-virtualized';

const VirtualizedInfiniteMultiGridComponent = ({ isLoading, items, canLoadMore, next }) => {
  const ref = useInfiniteScroll({
    next,
    columnCount: items.length,
    hasMore: { right: canLoadMore },
  });

  // Use `useCallback` so we don't recreate the function on each render - Could result in infinite loop
  const selectRef = useCallback(
    (node) => {
      ref.current = node?._bottomRightGrid;
    },
    [ref]
  );

  return (
    <div>
      <MultiGrid ref={selectRef} {...props} />
      {isLoading && <div>Loading...</div>}
    </div>
  );
};

How to use it with react-window?

react-easy-infinite-scroll-hook works with any DOM element, so just specify the correct container for the ref object:

import React, { useCallback } from 'react';
import useInfiniteScroll from 'react-easy-infinite-scroll-hook';
import { FixedSizeList } from 'react-window';

const Component = ({ isLoading, items, canLoadMore, next }) => {
  const ref = useInfiniteScroll({
    next,
    columnCount: items.length,
    hasMore: { right: canLoadMore },
  });

  // Use `useCallback` so we don't recreate the function on each render - Could result in infinite loop
  const setRef = useCallback((node) => {
    if(node)
      ref.current=node._outerRef
  }, []);
  
  return (
    <FixedSizeList
      ref={setRef}
      className="List"
      width={600}
      height={500}
      itemSize={60}
      itemCount={items.length}
    >
      {Row}
    </FixedSizeList>);
};

Contributing

Please read through our contributing guidelines. Included are directions for opening issues, coding standards, and notes on development.

License

Code released under the MIT License.