index.js
Overview
This file implements a React functional component that displays GitHub issues from a specified repository with infinite scrolling and client-side pagination. It leverages the SWR Infinite hook (useSWRInfinite) for data fetching, caching, and pagination, combined with an intersection observer hook (useOnScreen) to trigger loading additional pages when the user scrolls to the bottom of the list.
The main functionality includes:
Fetching GitHub issues in pages of a fixed size (
PAGE_SIZE= 6).Allowing the user to input and change the GitHub repository to query (default:
facebook/react).Automatically loading more issues when the user scrolls near the bottom (infinite scroll).
Refreshing the issue list on demand.
Clearing the list of loaded issues.
This component provides a seamless user experience for browsing GitHub issues without manual page navigation.
Detailed Explanation
Constants
PAGE_SIZE
const PAGE_SIZE = 6
Defines the number of GitHub issues to fetch per API request (per page).
Used to control pagination size.
Utility Function
getKey(pageIndex, previousPageData, repo, pageSize)
const getKey = (pageIndex, previousPageData, repo, pageSize) => {
if (previousPageData && !previousPageData.length) return null // reached the end
return `https://api.github.com/repos/${repo}/issues?per_page=${pageSize}&page=${
pageIndex + 1
}`
}
Purpose: Generates the API endpoint URL for fetching issues for a given page.
Parameters:
pageIndex(number): The current page index (zero-based).previousPageData(array): Data returned from the previous page request.repo(string): The target GitHub repository inowner/repoformat.pageSize(number): Number of issues per page.
Returns:
A URL string for the GitHub API call for the current page.
Returns
nullwhen the previous page data is empty, signaling no more pages to fetch (end of pagination).
Usage:
Used as the key function in
useSWRInfiniteto control fetching based on page and repository.
Main Component
App (default export)
export default function App() { ... }
Type: React Functional Component
Purpose: Displays a paginated and infinitely scrollable list of GitHub issues for a specified repository.
State Variables:
repo(string): Current GitHub repo to fetch issues from. Default:'facebook/react'.val(string): Controlled input state linked to the repo input box.
Refs:
ref: Attached to a div element used for intersection observation.
Hooks:
useOnScreen(ref): Custom hook to detect if the referenced div is visible on the screen.useSWRInfinite: Handles fetching pages of issues, caching, and pagination state.
Derived Variables:
issues: Flattened array of all fetched issues from all pages.Loading and status flags:
isLoadingInitialData,isLoadingMore,isEmpty,isReachingEnd,isRefreshing.
Effects:
An effect triggers when the sentinel element (
ref) is visible, not reaching the end, and not currently refreshing, to increment the page size and load more issues (infinite scroll).
Event Handlers:
Input change updates
val."load issues" button updates
repoand resets page size to 1."refresh" button triggers SWR's
mutate()to refetch data."clear" button sets page size to 0, clearing the loaded data.
Rendered UI:
Input box for repo name.
Buttons for loading, refreshing, and clearing issues.
Status text showing pages loaded and number of issues.
List of issue titles.
Sentinel div to detect scroll position and trigger loading more.
Parameters and Return Values
The component does not take any props; it manages its own state internally.
Returns a JSX tree rendering the UI described above.
Usage Example
This component is intended to be used as the main or a sub-component in a React application where the user wants to browse issues from any GitHub repository.
import React from 'react'
import App from './index'
function Main() {
return <App />
}
This will render the input and the infinite-scrolling issues list.
Implementation Details and Algorithms
Infinite Scrolling:
The component uses the intersection observer hookuseOnScreento detect when the sentinel div at the bottom of the list is visible. When visible, and if not currently loading or at the end of available data, it increments the page size (setSize(size + 1)), triggering SWR to fetch the next page.Data Fetching with SWR Infinite:
useSWRInfinitemanages fetching paginated data from GitHub's API. It usesgetKeyto generate the API URL for the current page, andfetcher(an imported abstraction forfetch) to perform the HTTP request. The data is cached and revalidated automatically by SWR.End of Pagination Detection:
WhenpreviousPageDatais an empty array,getKeyreturnsnull, telling SWR no more pages exist, stopping further fetches.State Synchronization Between Input and Repo:
valholds the input field value, whilerepoholds the actual repo used for fetching. The user editsval; clicking "load issues" updatesrepoand triggers a fresh fetch.UI Feedback:
The component shows loading states, no issues found message, and disables buttons appropriately to reflect current loading or interaction states.
Interaction with Other Parts of the Application
Imports:
useSWRInfinitefrom'swr/infinite': Provides infinite loading and caching capabilities.fetcherfrom'../libs/fetch': Abstracted fetch function for HTTP requests.useOnScreenfrom'../hooks/useOnScreen': Custom hook to detect element visibility on screen.
This Component's Role:
It acts as a UI layer component responsible for rendering paginated GitHub issues. It relies on hooks and utility functions abstracted elsewhere (fetcher,useOnScreen), making it modular and focused on UI logic.
Visual Diagram
flowchart TD
A[App Component] --> B[State: repo, val]
A --> C[useRef: ref for sentinel div]
A --> D[useOnScreen(ref) -> isVisible]
A --> E[useSWRInfinite(getKey, fetcher) -> data, error, mutate, size, setSize, isValidating]
E --> F[Data Fetching per page]
F --> G(API URL: getKey(pageIndex, previousPageData, repo, PAGE_SIZE))
A --> H[Effects]
H --> I[On isVisible & not end & not refreshing -> setSize(size + 1)]
A --> J[Event Handlers]
J --> K[Input change -> setVal]
J --> L[Click "load issues" -> setRepo(val), setSize(1)]
J --> M[Click "refresh" -> mutate()]
J --> N[Click "clear" -> setSize(0)]
A --> O[Render UI]
O --> P[Input box, Buttons]
O --> Q[List of issues]
O --> R[Sentinel div with ref]
Summary
This file defines a React component that interactively fetches, paginates, and displays GitHub issues from any user-supplied repository. It employs useSWRInfinite for data management and an intersection observer hook for infinite scroll triggering, providing a responsive and user-friendly interface to browse GitHub issues efficiently.