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:
Dynamic Pagination Keys: It generates a fetch key for each page based on the current page index and the selected repository, enabling SWR to cache and fetch data page-by-page.
Page Size Management: Using the
sizeandsetSizecontrols fromuseSWRInfinite, it tracks how many pages are loaded and allows the user to load more by incrementing the page count.Concatenation and Status Tracking: It flattens the array of page results into a single list of issues and computes various loading states such as initial loading, loading more pages, reaching the end (no more data), and refreshing.
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:
Load More: Increases the page count to fetch the next page.
Refresh: Revalidates all loaded pages.
Clear: Resets the loaded pages to zero.
Repository Input: Allows changing the repository and resets pagination.
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:
Core Data Fetching: Uses the SWR infinite hook to maintain cached pages independently while enabling concatenated consumption.
Error Handling and Retry Logic: Relies on SWR’s built-in error states and revalidation triggers for robustness.
Middleware Architecture: Although not explicitly shown here, this example can integrate middleware for features like preloading or subscription to updates on paginated data.
Developer Tooling: The example's clear state indicators aid debugging and usability during development.
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.