Live coding · 40 minutes
Infinite list with IntersectionObserver
Build a list in React that loads more items as the user scrolls, in 40 minutes. Use a public test API with pages, or a fake function that returns 20 items after a delay and ends after 5 pages. Use IntersectionObserver on an element at the end of the list, not a scroll event listener. Show loading, error and end-of-list states. Explain your decisions while you code, as in a live round.
Requirements
- The first page loads on mount; the next page loads when a sentinel element at the end of the list becomes visible
- Only one request runs at a time, and no page is added to the list twice
- A loading indicator shows at the end of the list while a page loads
- After the last page, loading stops and an end message is shown
- A failed request shows an error with a Retry button and keeps the loaded items
- The observer is disconnected when the component unmounts
- Items have stable keys from their ids
What reviewers look for
- IntersectionObserver is created in an effect with cleanup, with a rootMargin so loading starts before the user reaches the end
- No duplicate or parallel requests: a guard for loading and for hasMore
- No stale closure: the observer callback sees the current page and loading state
- Correct under Strict Mode, where effects run twice in development
- All states are handled: first load, next page, error with retry, end of list
- You can say why IntersectionObserver is better here than a scroll listener
Check before you hand it in
- Scrolling to the end loads the next page, again and again, until the last page
- No item appears twice, also when I scroll fast, and the network panel shows no two finished requests for the same page
- After the last page no more requests are sent, and an end message is shown
- I forced a failed request: an error and a Retry button appeared, the loaded items stayed, and Retry loaded the same page
- The effect cleanup disconnects the observer
- I explained each decision aloud, including why I use IntersectionObserver and not a scroll event
- Loading more on scroll, with the loading and end states, worked within 40 minutes
If there is time
- Add a Load more button as a fallback and for keyboard users
- Virtualize the list, so only the visible items are in the DOM
- Move the logic into a hook, for example useInfiniteList
- Restore the scroll position after a visit to a detail page