### Install react-infinite-scroll-component
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/README.md
Install the library using npm, yarn, or pnpm. No specific setup is required beyond installation.
```bash
npm install react-infinite-scroll-component
# or
yarn add react-infinite-scroll-component
# or
pnpm add react-infinite-scroll-component
```
--------------------------------
### Install react-infinite-scroll-component with yarn
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/AGENTS.md
Use this command to install the library using yarn.
```bash
yarn add react-infinite-scroll-component
```
--------------------------------
### Install react-infinite-scroll-component
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/llms.txt
Install the library using npm. This command adds the package to your project's dependencies.
```bash
npm install react-infinite-scroll-component
```
--------------------------------
### Example: Chat UI with Custom Scrollable Parent
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/scroll-modes.md
A complete example of a chat window using InfiniteScroll with a custom scrollable parent. This setup allows for bottom-anchored chat messages and efficient loading of older messages.
```typescript
function ChatWindow() {
const [messages, setMessages] = useState(initialMessages);
const [hasMore, setHasMore] = useState(true);
const chatRef = useRef(null);
const loadOlderMessages = async () => {
const older = await fetchMessages({ before: messages[0].timestamp });
if (older.length === 0) {
setHasMore(false);
return;
}
setMessages(prev => [...older, ...prev]);
};
return (
);
}
```
--------------------------------
### Accessibility Example 1: Role and Label
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/README.md
This example demonstrates how to use the `role` and `aria-label` props to improve accessibility for screen readers, announcing the container and item count.
```APIDOC
## Accessibility
Pass `role` and a label so screen readers can announce the container and its item count correctly:
```tsx
Loading...
}
>
{items.map((item) => (
{item.name}
))}
```
```
--------------------------------
### Accessibility Example 2: Aria-labelledby
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/README.md
This example shows how to reference an existing heading using the `aria-labelledby` prop for screen reader announcements.
```APIDOC
Or reference an existing heading via `aria-labelledby`:
```tsx
Search results
Loading...}
>
```
```
--------------------------------
### TanStack Query Integration Example
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/llms.txt
An example demonstrating how to integrate the react-infinite-scroll-component with TanStack Query for managing infinite scroll data fetching.
```APIDOC
## With TanStack Query
```tsx
import { useInfiniteQuery } from '@tanstack/react-query';
import InfiniteScroll from 'react-infinite-scroll-component';
function Feed() {
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({
queryKey: ['items'],
queryFn: ({ pageParam = 0 }) => fetchItems(pageParam),
getNextPageParam: (last, pages) => last.length === 20 ? pages.length : undefined,
});
const items = data?.pages.flat() ?? [];
return (
Loading... : null}
>
{items.map(item =>
{item.title}
)}
);
}
```
```
--------------------------------
### CommonJS Import Example
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/module-exports.md
Demonstrates how to import the InfiniteScroll component and its hooks using the CommonJS `require` syntax, suitable for Node.js environments.
```javascript
const InfiniteScroll = require('react-infinite-scroll-component');
const { useInfiniteScroll } = require('react-infinite-scroll-component');
// Use exactly as in ESM
```
--------------------------------
### Basic Infinite Scroll Usage
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/use-infinite-scroll-hook.md
Demonstrates the fundamental setup for infinite scrolling. It fetches more items when the user scrolls to the end of the list.
```typescript
import { useState } from 'react';
import { useInfiniteScroll } from 'react-infinite-scroll-component';
function Feed() {
const [items, setItems] = useState(initialItems);
const [hasMore, setHasMore] = useState(true);
const { sentinelRef, isLoading } = useInfiniteScroll({
next: async () => {
const more = await fetchItems(items.length);
if (more.length === 0) {
setHasMore(false);
return;
}
setItems((prev) => [...prev, ...more]);
},
hasMore,
dataLength: items.length,
});
return (
{items.map((item) => (
{item.name}
))}
{isLoading &&
Loading...
}
{!hasMore &&
All items loaded.
}
);
}
```
--------------------------------
### RootMargin Calculation Example
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/performance-and-internals.md
Illustrates how the `buildRootMargin` function converts a user-defined `scrollThreshold` into a CSS `rootMargin` string for IntersectionObserver. This example shows the conversion process and the resulting root margin for a specific threshold and inverse setting.
```typescript
scrollThreshold: 0.8, inverse: false
↓
parseThreshold(0.8) → { unit: 'Percent', value: 80 }
↓
buildRootMargin(0.8, false)
remaining = 100 - 80 = 20
return "0px 0px 20% 0px" // bottom margin
↓
IntersectionObserver rootMargin: "0px 0px 20% 0px"
Sentinel fires when within 20% of the bottom
```
--------------------------------
### Basic Pull-to-Refresh Implementation
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/pull-to-refresh.md
Implement basic pull-to-refresh by enabling the `pullDownToRefresh` prop and providing a `refreshFunction`. This example shows how to fetch new data and update the list when the user pulls down.
```typescript
import { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
function Feed() {
const [items, setItems] = useState(initialItems);
const [hasMore, setHasMore] = useState(true);
const refreshList = async () => {
const fresh = await api.getLatest();
setItems(fresh);
// hasMore stays true because we reloaded the entire list
};
const fetchMore = async () => {
const next = await api.getMore({ offset: items.length });
if (next.length === 0) {
setHasMore(false);
return;
}
setItems(prev => [...prev, ...next]);
};
return (
Loading...}
pullDownToRefresh
refreshFunction={refreshList}
pullDownToRefreshContent={
↓ Pull down to refresh
}
releaseToRefreshContent={
↑ Release to refresh
}
>
{items.map(item => (
{item.title}
))}
);
}
```
--------------------------------
### Basic Infinite Scroll with Window Scroll
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/infinite-scroll-component.md
Demonstrates a basic infinite scroll setup that utilizes the browser window for scrolling. It fetches more items when the user scrolls to the bottom.
```typescript
import { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
function Feed() {
const [items, setItems] = useState(initialItems);
const [hasMore, setHasMore] = useState(true);
const fetchMore = async () => {
const next = await api.getItems({ offset: items.length });
if (next.length === 0) {
setHasMore(false);
return;
}
setItems((prev) => [...prev, ...next]);
};
return (
Loading...}
endMessage={
All items loaded.
}
>
{items.map((item) => (
{item.name}
))}
);
}
```
--------------------------------
### InfiniteScroll Component API
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/COMPLETION_SUMMARY.txt
Documentation for the main InfiniteScroll component, detailing its props, behavior, and usage examples.
```APIDOC
## InfiniteScroll Component
### Description
The `InfiniteScroll` component is the primary way to implement infinite scrolling functionality in your React application. It handles loading more items as the user scrolls down the page.
### Props
#### Props Interface (`Props`)
- **`children`** (ReactNode) - Required - The content to be rendered, typically a list of items.
- **`dataLength`** (number) - Required - The total number of data items currently rendered. Used to determine if more data needs to be loaded.
- **`next`** (function) - Required - A function to call when more data needs to be fetched. This function should update the `dataLength` and provide new items.
- **`hasMore`** (boolean) - Required - A flag indicating whether there are more items to load. If `false`, the `next` function will not be called.
- **`loader`** (ReactNode) - Optional - A component or element to display while new data is being loaded.
- **`endMessage`** (ReactNode) - Optional - A message to display when all items have been loaded and `hasMore` is `false`.
- **`pullDownToRefresh`** (boolean) - Optional - Enables pull-to-refresh functionality on mobile devices.
- **`pullDownToRefreshContent`** (ReactNode) - Optional - Custom content to display during the pull-to-refresh gesture.
- **`releaseToRefreshContent`** (ReactNode) - Optional - Custom content to display when the user releases to trigger a refresh.
- **`refreshFunction`** (function) - Optional - The function to call when a refresh is triggered by the pull-to-refresh gesture.
- **`height`** (number) - Optional - The height of the scrollable container in pixels. If not provided, it defaults to the window height.
- **`scrollThreshold`** (string | number) - Optional - Specifies how close to the end of the scrollable area the user must be to trigger loading more items. Can be a number (percentage) or a string (e.g., '100px').
- **`inverse`** (boolean) - Optional - If `true`, enables inverse scrolling, useful for chat-like interfaces where new items appear at the top.
- **`containerClassName`** (string) - Optional - CSS class name to apply to the scrollable container.
- **`style`** (object) - Optional - Inline styles to apply to the scrollable container.
### Behavior Documentation
- **Loader**: The `loader` prop is displayed when `next` is called and `hasMore` is `true`.
- **End Message**: The `endMessage` prop is displayed when `hasMore` becomes `false`.
- **Pull-to-refresh**: If enabled, users can pull down to trigger a refresh action defined by `refreshFunction`.
- **Inverse Scroll**: When `inverse` is true, new items are added to the top, and the scroll position is adjusted accordingly.
### DOM Structure and Lifecycle Effects
The component manages its own DOM structure to facilitate scrolling and loading. It utilizes IntersectionObserver internally for efficient scroll detection.
### Usage Examples
Refer to the `infinite-scroll-component.md` file for detailed usage examples covering various scenarios.
```
--------------------------------
### Complete Feed with All Features
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/quick-reference.md
A comprehensive example of a feed component that includes infinite scrolling, pull-to-refresh functionality, and standard loader/end messages. Ensure you have an `api` object with `getItems` and `getLatest` methods.
```typescript
function Feed() {
const [items, setItems] = useState(initialItems);
const [hasMore, setHasMore] = useState(true);
const fetchMore = async () => {
const next = await api.getItems({ offset: items.length });
if (!next.length) return setHasMore(false);
setItems(prev => [...prev, ...next]);
};
const refresh = async () => {
const fresh = await api.getLatest();
setItems(fresh);
};
return (
Loading...}
endMessage={
))}
>
);
}
```
--------------------------------
### Custom UI with useInfiniteScroll Hook
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/inverse-scroll.md
Create a custom UI for infinite scrolling using the `useInfiniteScroll` hook. This example demonstrates how to manage loading states and attach the scroll listener to a specific element.
```typescript
import { useInfiniteScroll } from 'react-infinite-scroll-component';
function CustomChatUI() {
const [messages, setMessages] = useState([]);
const [hasMore, setHasMore] = useState(true);
const { sentinelRef, isLoading } = useInfiniteScroll({
next: async () => {
const older = await api.getOlderMessages(messages[0]?.id);
if (older.length === 0) {
setHasMore(false);
} else {
setMessages(prev => [...older, ...prev]);
}
},
hasMore,
dataLength: messages.length,
inverse: true,
});
return (
{/* Sentinel at top (appears at bottom visually due to column-reverse) */}
{isLoading &&
Loading older messages...
}
{messages.map(msg => (
{msg.text}
))}
);
}
```
--------------------------------
### InfiniteScroll component for window scroll
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/AGENTS.md
Example of using the InfiniteScroll component for a feed-style layout with window scrolling. Ensure you have a fetchMore function and manage the items and hasMore state.
```tsx
import { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
type Item = { id: number; name: string };
function Feed() {
const [items, setItems] = useState(initialItems);
const [hasMore, setHasMore] = useState(true);
const fetchMore = async () => {
const next = await api.getItems({ offset: items.length });
if (next.length === 0) {
setHasMore(false);
return;
}
setItems((prev) => [...prev, ...next]);
};
return (
Loading...}
endMessage={
No more items.
}
>
{items.map((item) => (
{item.name}
))}
);
}
```
--------------------------------
### Basic Infinite Scroll Usage in TypeScript
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/README.md
Demonstrates the fundamental setup for InfiniteScroll with state management for items and 'hasMore' flag. Requires initial data and an API function to fetch more items.
```tsx
import { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
type Item = { id: number; name: string };
function Feed() {
const [items, setItems] = useState(initialItems);
const [hasMore, setHasMore] = useState(true);
const fetchMore = async () => {
const next = await api.getItems({ offset: items.length });
if (next.length === 0) {
setHasMore(false);
return;
}
setItems((prev) => [...prev, ...next]);
};
return (
Loading...}
endMessage={
All items loaded.
}
>
{items.map((item) => (
{item.name}
))}
);
}
```
--------------------------------
### Create Generic Infinite List Component
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/types.md
This example illustrates creating a generic React functional component that wraps InfiniteScroll, allowing for typed lists of items.
```typescript
function createInfiniteList(): React.FC {
return (props) => {
const { items, ...rest } = props;
return (
{items.map((item) => (
{item.name}
))}
);
};
}
```
--------------------------------
### Use Props Type for Custom Wrapper
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/types.md
This example shows how to create a custom wrapper component for InfiniteScroll, utilizing its exported Props type for type safety.
```typescript
import { Props as InfiniteScrollProps } from 'react-infinite-scroll-component';
function CustomInfiniteScroll(props: InfiniteScrollProps) {
return ;
}
```
--------------------------------
### Effect Dependencies for Observer Re-creation
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/performance-and-internals.md
Specifies dependencies for a useEffect hook that controls observer setup. The observer is recreated only when configuration-related props change, balancing performance and responsiveness.
```typescript
// Recreates observer when config changes
useEffect(() => {
// observer setup
}, [hasMore, scrollThreshold, inverse, height, getScrollableNode]);
```
--------------------------------
### Basic Chat UI with Inverse Infinite Scroll
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/inverse-scroll.md
A complete example of implementing inverse scrolling for a chat interface. It uses `react-infinite-scroll-component` to load older messages when the user scrolls towards the top of the chat container.
```typescript
import { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
function ChatRoom() {
const [messages, setMessages] = useState(initialMessages);
const [hasMore, setHasMore] = useState(true);
const loadOlderMessages = async () => {
const older = await api.getMessages({
before: messages[0].timestamp,
limit: 20,
});
if (older.length === 0) {
setHasMore(false);
return;
}
// Prepend older messages to the list
setMessages(prev => [...older, ...prev]);
};
return (
);
}
```
--------------------------------
### Inverse Scroll Accessibility Example
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/inverse-scroll.md
Implement semantic structure for screen readers using ARIA roles and attributes when using inverse scroll. Ensure new messages are announced politely.
```typescript
```
--------------------------------
### InfiniteScroll component with ref for fixed-height container
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/AGENTS.md
Alternative to using an ID, this example shows how to use a ref to specify the scrollable container for the InfiniteScroll component. Ensure the ref is correctly attached to the scrollable element.
```tsx
const containerRef = useRef(null);
;
```
--------------------------------
### Styling the Pull Indicator with CSS
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/pull-to-refresh.md
Apply CSS classes to the custom pull indicator elements to control their appearance. This example demonstrates basic styling for padding, text alignment, and background gradients, as well as state-specific text colors.
```css
.pull-indicator {
padding: 20px;
text-align: center;
background: linear-gradient(to bottom, #f0f0f0, transparent);
}
.pull-state p {
color: #999;
}
.release-state p {
color: #4CAF50;
font-weight: bold;
}
```
--------------------------------
### UMD Browser Import
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/module-exports.md
Include the library via a CDN and access exports through the global `window.ReactInfiniteScrollComponent` object for browser environments.
```html
```
--------------------------------
### Chat with Pull-to-Refresh
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/inverse-scroll.md
Implement inverse scroll with pull-to-refresh for loading the latest messages in a chat interface. This example uses the `pullDownToRefresh` and `refreshFunction` props.
```typescript
function ChatWithRefresh() {
const [messages, setMessages] = useState(initialMessages);
const [hasMore, setHasMore] = useState(true);
const loadLatestMessages = async () => {
// Refresh gets the most recent messages
const latest = await api.getLatestMessages();
setMessages(latest);
setHasMore(true); // Reset to allow loading older again
};
const loadOlderMessages = async () => {
const older = await api.getMessages({ before: messages[0].timestamp });
if (older.length === 0) {
setHasMore(false);
return;
}
setMessages(prev => [...older, ...prev]);
};
return (
);
}
```
--------------------------------
### Basic Import and Usage
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/module-exports.md
Demonstrates the standard way to import the InfiniteScroll component and use it within JSX. Ensure you have dataLength, next, hasMore, and loader props defined.
```typescript
import InfiniteScroll from 'react-infinite-scroll-component';
// In JSX
Loading...}
>
{items.map(item =>
{item.name}
)}
```
--------------------------------
### Infinite Scroll Component Window Scroll Mode
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/quick-reference.md
Example of using the InfiniteScroll component for window scroll mode. Omit scrollableTarget and height props.
```typescript
Loading...}
>
{items}
```
--------------------------------
### Manual buildRootMargin Usage
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/build-root-margin.md
Demonstrates manual usage of the buildRootMargin utility function for custom scroll observer implementations. It shows how to generate rootMargin strings for different scenarios, including pixel and percentage values, and inverse mode.
```typescript
import { buildRootMargin } from 'react-infinite-scroll-component';
const margin1 = buildRootMargin(0.8, false);
// Returns: "0px 0px 20% 0px"
const margin2 = buildRootMargin("300px", false);
// Returns: "0px 0px 300px 0px"
const margin3 = buildRootMargin(0.5, true);
// Returns: "50% 0px 0px 0px"
const observer = new IntersectionObserver(callback, {
root: containerRef.current,
rootMargin: margin1,
threshold: 0,
});
```
--------------------------------
### Infinite Scroll Component Fixed Height Scroll Mode
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/quick-reference.md
Example of using the InfiniteScroll component with a fixed height. Set the height prop to a number representing pixels.
```typescript
Loading...}
height={500}
>
{items}
```
--------------------------------
### Import useInfiniteScroll hook
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/AGENTS.md
Import the useInfiniteScroll hook for custom UI implementations.
```tsx
import { useInfiniteScroll } from 'react-infinite-scroll-component';
```
--------------------------------
### Import InfiniteScroll Component and Hook
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/quick-reference.md
Import the main InfiniteScroll component and the useInfiniteScroll hook along with their types.
```typescript
import InfiniteScroll from 'react-infinite-scroll-component';
import { useInfiniteScroll } from 'react-infinite-scroll-component';
import type {
UseInfiniteScrollOptions,
UseInfiniteScrollResult,
} from 'react-infinite-scroll-component';
```
--------------------------------
### Peer Dependencies for React Infinite Scroll Component
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/module-exports.md
The package requires React and ReactDOM versions 17 or higher. These must be installed separately as they are peer dependencies and not bundled with the package.
```json
{
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
}
```
--------------------------------
### UseInfiniteScrollOptions Interface
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/types.md
Options passed to the useInfiniteScroll hook to configure its behavior.
```APIDOC
## UseInfiniteScrollOptions Interface
### Description
Options passed to the `useInfiniteScroll` hook.
### Fields
#### `next`
- **Type**: `() => void`
- **Required**: yes
- **Description**: Callback when sentinel enters viewport.
#### `hasMore`
- **Type**: `boolean`
- **Required**: yes
- **Description**: Whether more data exists.
#### `dataLength`
- **Type**: `number`
- **Required**: yes
- **Description**: Current item count.
#### `scrollThreshold`
- **Type**: `number | string`
- **Required**: no
- **Default**: `0.8`
- **Description**: Trigger point for the load.
#### `scrollableTarget`
- **Type**: `HTMLElement | string | null`
- **Required**: no
- **Description**: Custom scroll root element.
#### `inverse`
- **Type**: `boolean`
- **Required**: no
- **Default**: `false`
- **Description**: Reverse scroll direction.
```
--------------------------------
### Hook Import and Usage
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/module-exports.md
Shows how to import and utilize the useInfiniteScroll hook for managing infinite scroll logic. It returns a sentinelRef for the scrollable element and an isLoading state.
```typescript
import { useInfiniteScroll } from 'react-infinite-scroll-component';
const { sentinelRef, isLoading } = useInfiniteScroll({
next: loadMore,
hasMore: hasMore,
dataLength: items.length,
});
```
--------------------------------
### useInfiniteScroll Hook Props and Returns
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/llms.txt
This section details the props accepted by the useInfiniteScroll hook and the values it returns, facilitating programmatic infinite scrolling.
```APIDOC
## All props, useInfiniteScroll hook
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| `dataLength` | `number` | yes | | Length of the full rendered list. |
| `next` | `() => void` | yes | | Fetch next page. |
| `hasMore` | `boolean` | yes | | false = disconnect observer. |
| `scrollThreshold` | `number \| string` | no | `0.8` | Trigger distance. |
| `scrollableTarget` | `HTMLElement \| string \| null` | no | | Observer root. |
| `inverse` | `boolean` | no | `false` | Observe from top. |
Returns: `{ sentinelRef: RefObject, isLoading: boolean }`
```
--------------------------------
### Infinite Scroll Component Custom Parent Scroll Mode
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/quick-reference.md
Example of using the InfiniteScroll component with a custom parent scrollable element. Use the scrollableTarget prop with the ID of the parent element.
```typescript
Loading...}
scrollableTarget="scroll"
>
{items}
```
--------------------------------
### Disable Pull-to-Refresh When Not at Top
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/pull-to-refresh.md
Control the pull-to-refresh functionality based on the scroll position. The component prevents pulling when scrollTop > 0, but this example adds explicit logic to manage the `canRefresh` state.
```typescript
const [canRefresh, setCanRefresh] = useState(true);
const handleScroll = (e) => {
const scrollTop = e.target.scrollTop;
setCanRefresh(scrollTop === 0);
};
return (
{items}
);
```
--------------------------------
### Number Input - Fraction to Percentage Conversion
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/parse-threshold.md
Handles number inputs by interpreting them as fractions of container height, converting them to percentages, and returning the result.
```typescript
// Input: 0.8 → Output: { unit: 'Percent', value: 80 }
// Input: 0.5 → Output: { unit: 'Percent', value: 50 }
// Input: 1 → Output: { unit: 'Percent', value: 100 }
// Input: 0.2 → Output: { unit: 'Percent', value: 20 }
```
--------------------------------
### Implement Pagination for Data Fetching
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/quick-reference.md
Manage data fetching by storing and updating offset and limit values instead of loading all items at once. This approach is useful for large datasets.
```typescript
const [offset, setOffset] = useState(0);
next: async () => {
const page = await fetchPage(offset);
setItems(prev => [...prev, ...page]);
setOffset(offset + 20);
}
```
--------------------------------
### Comment Thread (Newest Last)
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/inverse-scroll.md
Display a comment thread with the newest comments appearing last, utilizing inverse scrolling. This example focuses on loading older comments when the user scrolls up.
```typescript
function CommentThread() {
const [comments, setComments] = useState(initialComments);
const [hasMore, setHasMore] = useState(true);
const loadOlderComments = async () => {
const older = await api.getComments({
postId: currentPost.id,
before: comments[0].id,
});
if (older.length === 0) {
setHasMore(false);
return;
}
setComments(prev => [...older, ...prev]);
};
return (
);
}
```
--------------------------------
### Multiple Independent Infinite Scroll Lists
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/use-infinite-scroll-hook.md
Demonstrates how to manage multiple independent infinite scroll lists on the same page, each with its own hook instance, sentinel, and loading state.
```typescript
function MultiListPage() {
const [list1, setList1] = useState([]);
const [list1More, setList1More] = useState(true);
const [list2, setList2] = useState([]);
const [list2More, setList2More] = useState(true);
const list1Hook = useInfiniteScroll({
next: async () => {
const more = await api.fetchList1(list1.length);
setList1((prev) => [...prev, ...more]);
if (more.length < 20) setList1More(false);
},
hasMore: list1More,
dataLength: list1.length,
});
const list2Hook = useInfiniteScroll({
next: async () => {
const more = await api.fetchList2(list2.length);
setList2((prev) => [...prev, ...more]);
if (more.length < 20) setList2More(false);
},
hasMore: list2More,
dataLength: list2.length,
});
return (
{list1.map((item) => (
{item.name}
))}
{list1Hook.isLoading &&
Loading list 1...
}
{list2.map((item) => (
{item.name}
))}
{list2Hook.isLoading &&
Loading list 2...
}
);
}
```
--------------------------------
### Accessibility: Announce Loading State
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/use-infinite-scroll-hook.md
Use a separate live region with `role="status"` and `aria-live="polite"` to announce loading state to screen readers.
```typescript
\n
\n {isLoading && Loading more items}\n
```
--------------------------------
### InfiniteScroll component for fixed-height container scroll
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/AGENTS.md
Example of using the InfiniteScroll component within a fixed-height container that has overflow enabled. The scrollableTarget prop must be set to the ID of the scrollable element.
```tsx
```
--------------------------------
### useInfiniteScroll Hook API
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/COMPLETION_SUMMARY.txt
Documentation for the `useInfiniteScroll` hook, detailing its options, return values, behavior, and integration patterns.
```APIDOC
## useInfiniteScroll Hook
### Description
The `useInfiniteScroll` hook provides a programmatic way to manage infinite scrolling logic within your components, offering more flexibility than the `InfiniteScroll` component.
### Options (`UseInfiniteScrollOptions`)
- **`next`** (function) - Required - Function to call when more data needs to be fetched.
- **`hasMore`** (boolean) - Required - Indicates if there are more items to load.
- **`scrollThreshold`** (string | number) - Optional - Threshold for triggering `next`. Similar to the `InfiniteScroll` component's prop.
- **`inverse`** (boolean) - Optional - Enables inverse scrolling behavior.
### Return Value (`UseInfiniteScrollResult`)
- **`containerRef`** (RefObject) - A ref object to attach to the scrollable container element.
- **`loader`** (ReactNode) - The loader element to be rendered when data is loading.
- **`endMessage`** (ReactNode) - The end message element to be rendered when `hasMore` is false.
### Behavior and Lifecycle
The hook manages the scroll event listeners and IntersectionObserver instances internally. It updates the state related to loading and end-of-list conditions based on the provided options and scroll position.
### Usage Examples
Refer to the `use-infinite-scroll-hook.md` file for detailed usage examples and integration patterns.
```
--------------------------------
### Document Dependencies
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/INDEX.md
This code block lists the markdown files that form the documentation structure for the react-infinite-scroll-component. It shows the entry point and the various sub-documents.
```markdown
README.md (entry point)
├── quick-reference.md (patterns & examples)
├── infinite-scroll-component.md (main component)
├── use-infinite-scroll-hook.md (hook API)
├── scroll-modes.md (scroll configuration)
├── pull-to-refresh.md (feature guide)
├── inverse-scroll.md (feature guide)
├── types.md (TypeScript types)
├── module-exports.md (import paths)
├── build-root-margin.md (utility)
├── parse-threshold.md (utility)
└── performance-and-internals.md (advanced)
```
--------------------------------
### Chat with Inverse Scroll
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/quick-reference.md
Example of implementing inverse scrolling for a chat interface, where new messages appear at the bottom and older messages load upwards. Requires a scrollable target element with `flexDirection: 'column-reverse'`.
```typescript
function Chat() {
const [messages, setMessages] = useState([]);
const [hasMore, setHasMore] = useState(true);
return (
);
}
```
--------------------------------
### Animated Pull-to-Refresh Indicators
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/pull-to-refresh.md
Create animated pull-to-refresh indicators by manipulating CSS `transform` and `transition` properties within the `pullDownToRefreshContent` and `releaseToRefreshContent` props. This example uses a rotating arrow to indicate the refresh state.
```typescript
import { useRef } from 'react';
function AnimatedPullToRefresh() {
const rotationRef = useRef(0);
return (
⬇️
Pull to refresh
}
releaseToRefreshContent={
⬇️
Release to refresh
}
// ... other props
>
{/* Items */}
);
}
```
--------------------------------
### Configure Built-in UI Elements
Source: https://github.com/ankeetmaini/react-infinite-scroll-component/blob/master/_autodocs/README.md
Customize the loader, end message, and pull-to-refresh UI using built-in props.
```typescript
// All built-in UI
}
endMessage={