Infinite Scroll Example

Purpose

This example demonstrates how to implement infinite loading of paginated data within a React component using the useSWRInfinite hook. It addresses the common challenge of efficiently fetching and displaying large datasets in chunks (pages) rather than loading everything at once. Specifically, it fetches GitHub issues for a given repository, allowing users to load more pages incrementally or refresh the existing data.

Functionality

The component manages three core concerns unique to infinite scrolling with SWR:

Key parts that enable this functionality include:

// Generate fetch key per page
const { data, size, setSize, mutate, error, isValidating } = useSWRInfinite(
  (index) =>
    `https://api.github.com/repos/${repo}/issues?per_page=${PAGE_SIZE}&page=${index + 1}`,
  fetch
)

// Flatten paginated data into a single list
const issues = data ? [].concat(...data) : []

// Determine loading states
const isLoadingInitialData = !data && !error
const isLoadingMore =
  isLoadingInitialData || (size > 0 && data && typeof data[size - 1] === 'undefined')
const isEmpty = data?.[0]?.length === 0
const isReachingEnd = isEmpty || (data && data[data.length - 1]?.length < PAGE_SIZE)
const isRefreshing = isValidating && data && data.length === size

User interactions supported:

These controls work seamlessly with SWR’s caching and revalidation, providing a smooth infinite scroll experience.

Integration

This infinite scroll example builds directly upon the core SWR hook by leveraging the useSWRInfinite extension, which specializes in managing paginated data. It complements the parent topic of example applications demonstrating SWR use cases by showcasing how to handle multi-page fetching patterns.

Integration points include:

By illustrating these concepts in a concrete, practical example, it extends the parent topic's coverage with a specific, real-world pattern for paginated data fetching in React applications.

Diagram

flowchart TD
  UserInput[User inputs repo name] --> SetRepo[Set repo state and reset size to 1]
  SetRepo --> FetchPage1[useSWRInfinite fetches page 1]
  FetchPage1 --> DisplayData[Display issues from page 1]
  DisplayData --> LoadMoreBtn[User clicks "Load More"]
  LoadMoreBtn --> IncrementSize[Increment page size]
  IncrementSize --> FetchNextPage[useSWRInfinite fetches next page]
  FetchNextPage --> DisplayData
  DisplayData --> RefreshBtn[User clicks "Refresh"]
  RefreshBtn --> Mutate[Trigger SWR mutate() to revalidate all pages]
  Mutate --> FetchAllPages[Re-fetch all loaded pages]
  FetchAllPages --> DisplayData
  DisplayData --> ClearBtn[User clicks "Clear"]
  ClearBtn --> ResetSize[Reset page size to 0]
  ResetSize --> EmptyDisplay[No data shown]

This flowchart visualizes the core user-driven workflows for loading, refreshing, and clearing paginated data within the infinite scroll example.