Build a fixed-height virtual list for 10,000 activity records. The scrollbar must represent the whole dataset, while React mounts only the visible slice plus a small overscan buffer.
The polished starter renders the complete resting view and its 440,000px spacer, but the first slice stays pinned when you scroll. Add React state, an onScroll handler, and render-time derivations.
scrollTop with useState(0) and update it from event.currentTarget.scrollTop.start, from, to, offset, and visible on every render. Do not store the slice separately.from * ROW_HEIGHT, render only ITEMS.slice(from, to), and keep both footer counts in sync.TOTAL = 10000, ROW_HEIGHT = 44, VIEWPORT_HEIGHT = 352, and OVERSCAN = 3.start = floor(scrollTop / ROW_HEIGHT), from = max(0, start - OVERSCAN), and to = min(TOTAL, start + ceil(VIEWPORT_HEIGHT / ROW_HEIGHT) + OVERSCAN).Showing 1–11 of 10,000, and show 11 row nodes. At scrollTop = 4400, render items 98–111 and translate the window to 4268px.role="list"; rows are role="listitem" with aria-setsize="10000" and one-based aria-posinset; the readout is a polite status.styles.css when the solution replaces App.tsx.The full solution is part of Premium
Walkthrough, edge cases, complexity notes, and the runnable editor unlock with a Premium subscription.
Submissions are part of Premium
Unlock community code, comments, reactions, and framework-specific approaches.
Build a fixed-height virtual list for 10,000 activity records. The scrollbar must represent the whole dataset, while React mounts only the visible slice plus a small overscan buffer.
The polished starter renders the complete resting view and its 440,000px spacer, but the first slice stays pinned when you scroll. Add React state, an onScroll handler, and render-time derivations.
scrollTop with useState(0) and update it from event.currentTarget.scrollTop.start, from, to, offset, and visible on every render. Do not store the slice separately.from * ROW_HEIGHT, render only ITEMS.slice(from, to), and keep both footer counts in sync.TOTAL = 10000, ROW_HEIGHT = 44, VIEWPORT_HEIGHT = 352, and OVERSCAN = 3.start = floor(scrollTop / ROW_HEIGHT), from = max(0, start - OVERSCAN), and to = min(TOTAL, start + ceil(VIEWPORT_HEIGHT / ROW_HEIGHT) + OVERSCAN).Showing 1–11 of 10,000, and show 11 row nodes. At scrollTop = 4400, render items 98–111 and translate the window to 4268px.role="list"; rows are role="listitem" with aria-setsize="10000" and one-based aria-posinset; the readout is a polite status.styles.css when the solution replaces App.tsx.The full solution is part of Premium
Walkthrough, edge cases, complexity notes, and the runnable editor unlock with a Premium subscription.
Submissions are part of Premium
Unlock community code, comments, reactions, and framework-specific approaches.
Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.