or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-react-infinite-scroller

Infinite scroll component for React that supports both window and element-based scrolling with customizable thresholds and reverse mode.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-infinite-scroller@1.2.x

To install, run

npx @tessl/cli install tessl/npm-react-infinite-scroller@1.2.0

index.mddocs/

React Infinite Scroller

React Infinite Scroller is a lightweight React component that provides infinite scrolling functionality for both window and element-based scroll detection. It supports customizable thresholds, reverse scrolling for chat-like interfaces, and passive event listeners for optimal performance.

Package Information

  • Package Name: react-infinite-scroller
  • Package Type: npm
  • Language: JavaScript (React component)
  • Installation: npm install react-infinite-scroller

Core Imports

import InfiniteScroll from 'react-infinite-scroller';

For CommonJS:

const InfiniteScroll = require('react-infinite-scroller');

Basic Usage

import React, { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroller';

function MyComponent() {
  const [items, setItems] = useState([]);
  const [hasMore, setHasMore] = useState(true);

  const loadMore = async (page) => {
    try {
      // Note: page starts from pageStart + 1 (so if pageStart=0, first call gets page=1)
      const response = await fetch(`/api/items?page=${page}`);
      const newItems = await response.json();
      
      if (newItems.length === 0) {
        setHasMore(false);
      } else {
        setItems(prevItems => [...prevItems, ...newItems]);
      }
    } catch (error) {
      console.error('Failed to load items:', error);
    }
  };

  return (
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMore}
      hasMore={hasMore}
      loader={<div className="loader" key={0}>Loading...</div>}
    >
      <div>
        {items.map((item, index) => (
          <div key={index}>{item.name}</div>
        ))}
      </div>
    </InfiniteScroll>
  );
}

Capabilities

InfiniteScroll Component

Core React component that handles infinite scroll functionality with comprehensive configuration options.

/**
 * React component for infinite scrolling functionality
 * @component
 */
function InfiniteScroll(props: InfiniteScrollProps): React.ReactElement;

interface InfiniteScrollProps {
  /** Content to be rendered inside the scroll container (required) */
  children: React.ReactNode;
  
  /** Callback function triggered when more content needs to be loaded (required)
   * @param page - Page number starting from pageStart + 1 */
  loadMore: (page: number) => void;
  
  /** HTML element type to render as container */
  element?: string | React.ComponentType;
  
  /** Whether more items are available to load
   * When false, all scroll event listeners are automatically removed */
  hasMore?: boolean;
  
  /** Whether to trigger loadMore on component mount */
  initialLoad?: boolean;
  
  /** Whether to load content when scrolling to top (chat-like behavior) */
  isReverse?: boolean;
  
  /** React element to display while loading */
  loader?: React.ReactNode;
  
  /** Starting page number for loadMore callback */
  pageStart?: number;
  
  /** Ref callback to access the scroll container element
   * Note: Called after internal ref processing for scroll detection */
  ref?: (node: HTMLElement | null) => void;
  
  /** Function to override default scroll parent detection */
  getScrollParent?: () => HTMLElement;
  
  /** Distance in pixels from scroll end to trigger loadMore */
  threshold?: number;
  
  /** Event listener capture option */
  useCapture?: boolean;
  
  /** Whether to use window scroll events or parent element events */
  useWindow?: boolean;
}

Default Props:

  • element: 'div'
  • hasMore: false
  • initialLoad: true
  • pageStart: 0
  • ref: null
  • threshold: 250
  • useWindow: true
  • isReverse: false
  • useCapture: false
  • loader: null
  • getScrollParent: null

Window Scroll Mode

Default behavior using window scroll events for infinite scrolling.

<InfiniteScroll
  pageStart={0}
  loadMore={loadFunc}
  hasMore={true}
  loader={<div className="loader" key={0}>Loading...</div>}
>
  {items}
</InfiniteScroll>

Element Scroll Mode

Infinite scrolling within a specific scrollable container element.

<div style={{height: '400px', overflow: 'auto'}}>
  <InfiniteScroll
    pageStart={0}
    loadMore={loadFunc}
    hasMore={true}
    loader={<div className="loader" key={0}>Loading...</div>}
    useWindow={false}
  >
    {items}
  </InfiniteScroll>
</div>

Custom Parent Element

Using a custom parent element for scroll calculations with getScrollParent.

function MyComponent() {
  const scrollParentRef = useRef(null);

  return (
    <div 
      style={{height: '400px', overflow: 'auto'}} 
      ref={scrollParentRef}
    >
      <div>
        <InfiniteScroll
          pageStart={0}
          loadMore={loadFunc}
          hasMore={true}
          loader={<div className="loader" key={0}>Loading...</div>}
          useWindow={false}
          getScrollParent={() => scrollParentRef.current}
        >
          {items}
        </InfiniteScroll>
      </div>
    </div>
  );
}

Reverse Scrolling (Chat Mode)

Loading content when scrolling to the top, useful for chat interfaces.

<InfiniteScroll
  pageStart={0}
  loadMore={loadFunc}
  hasMore={true}
  loader={<div className="loader" key={0}>Loading...</div>}
  isReverse={true}
>
  {messages}
</InfiniteScroll>

Instance Methods

setDefaultLoader

Sets a default loader component for all InfiniteScroll instances.

/**
 * Set a default loader for all InfiniteScroll components
 * @param loader - React element to use as default loader
 */
setDefaultLoader(loader: React.ReactNode): void;

Usage:

const infiniteScrollRef = useRef(null);

// Set default loader on component instance
useEffect(() => {
  if (infiniteScrollRef.current) {
    infiniteScrollRef.current.setDefaultLoader(
      <div className="default-loader">Loading more items...</div>
    );
  }
}, []);

return (
  <InfiniteScroll
    ref={infiniteScrollRef}
    pageStart={0}
    loadMore={loadFunc}
    hasMore={true}
  >
    {items}
  </InfiniteScroll>
);

Event Handling and Performance

The component automatically handles:

  • Passive event listeners: Uses passive listeners when supported for better performance
  • Event cleanup: Removes all event listeners on component unmount and when hasMore becomes false
  • Chrome optimization: Prevents Chrome hangups with specific mousewheel handling
  • Scroll position management: Maintains scroll position in reverse mode after new content loads
  • Page numbering: The loadMore callback receives page numbers starting from pageStart + 1

Common Patterns

Loading State Management

function InfiniteList() {
  const [items, setItems] = useState([]);
  const [hasMore, setHasMore] = useState(true);
  const [isLoading, setIsLoading] = useState(false);

  const loadMore = async (page) => {
    if (isLoading) return; // Prevent overlapping requests
    
    setIsLoading(true);
    try {
      const newItems = await fetchItems(page);
      if (newItems.length === 0) {
        setHasMore(false);
      } else {
        setItems(prev => [...prev, ...newItems]);
      }
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMore}
      hasMore={hasMore && !isLoading}
      loader={<div>Loading...</div>}
    >
      <div>
        {items.map((item, index) => (
          <div key={item.id || index}>{item.content}</div>
        ))}
      </div>
    </InfiniteScroll>
  );
}

Custom Threshold

<InfiniteScroll
  pageStart={0}
  loadMore={loadFunc}
  hasMore={true}
  threshold={100} // Trigger load when 100px from bottom
  loader={<div>Loading...</div>}
>
  {items}
</InfiniteScroll>

Error Handling

const loadMore = async (page) => {
  try {
    const newItems = await fetchItems(page);
    setItems(prev => [...prev, ...newItems]);
    setHasMore(newItems.length > 0);
  } catch (error) {
    console.error('Failed to load items:', error);
    setHasMore(false); // Stop further loading attempts
  }
};