medium+220 XP
Build infinite scroll
Render a scrollable list that starts with 20 items, labelled "Item 1" through "Item 20".
Scrolling within 50px of the bottom loads 20 more items, simulating a 300ms network request, up to a hard cap of 60 items total. Past the cap, scrolling to the bottom does nothing.
Requirements
- The scrollable element has `id="scroll-container"` and a fixed height with `overflow-y: auto` (or `scroll`).
- Each item is an element with `data-testid="list-item"`.
- While a page is loading, exactly one element with `data-testid="loading-indicator"` is present; it is absent otherwise, including once the cap is reached.
- The item count never exceeds 60.
Your workspace
import { useState } from "react"; const PAGE_SIZE = 20; const MAX_ITEMS = 60; export default function App() { const [items, setItems] = useState( Array.from({ length: PAGE_SIZE }, (_, i) => i + 1) ); const [loading, setLoading] = useState(false); function handleScroll(e) { // TODO: when scrolled within 50px of the bottom, and there is more to // load, simulate a 300ms fetch and append the next 20 items — but never // past MAX_ITEMS, and never while a fetch is already in flight. } return ( <div id="scroll-container" onScroll={handleScroll} style={{ height: 250, overflowY: "auto", border: "1px solid #ddd", fontFamily: "sans-serif" }} > {items.map((n) => ( <div key={n} data-testid="list-item" style={{ padding: 12, borderBottom: "1px solid #eee" }}> Item {n} </div> ))} {loading ? ( <div data-testid="loading-indicator" style={{ padding: 12, textAlign: "center" }}> Loading... </div> ) : null} </div> ); }
Ready to check it?
5 tests run against your rendered component, right here in your browser. Sign in to claim the XP when you pass.
Stuck? The react course covers the ideas this problem is built on.