L10: M3 Challenge
Build a complete listings page with pagination, caching, and advanced features
Time to put everything you've learned to the test! In this comprehensive challenge, you'll build an advanced listings page with pagination, caching, refresh functionality, and optional bonus features.
Challenge Overview
Objective: Build a fully-featured listings page that demonstrates mastery of useEffect, async data, state management, and custom hooks.
Time Estimate: 2-3 hours
Difficulty: ⭐⭐⭐ Intermediate to Advanced
Requirements
Required Features (Core Challenge)
You must implement these three features:
Pagination
- Display 6 listings per page
- Show current page and total pages
- "Previous" and "Next" buttons
- Disable buttons at boundaries (first/last page)
- Fetch only the listings for the current page
Refresh Button
- Manual refresh button to reload data
- Show loading state during refresh
- Properly cancel ongoing requests when refreshing
- Display success feedback after refresh
Response Caching
- Cache API responses by page number
- Don't re-fetch already loaded pages
- Clear cache on refresh
- Implement cache expiration (5 minutes)
Bonus Features (Optional)
Challenge yourself with these advanced features:
- Infinite Scroll - Load next page automatically when scrolling to bottom
- Search Debouncing - Implement search with 500ms delay
- Optimistic Updates - Show immediate feedback before API responds
- Loading Skeletons - Animated placeholder content instead of spinner
- Error Recovery - Automatic retry with exponential backoff
Getting Started
Review Your Current Code
Take a look at your current HomePage.jsx. You should have:
- Data fetching with
useEffect - Loading and error states
- Display of listings in a grid
Plan Your Approach
Before coding, think through:
-
State management: What state variables do you need?
currentPage,totalPages,cache,isRefreshing, etc.
-
API updates: How will you modify the mock API?
- Add pagination support:
getAllListings(page, perPage) - Return metadata:
{ listings, total, page, perPage }
- Add pagination support:
-
Custom hooks: Should you extract any logic?
usePaginatedListings?useCachedData?
Set Up Your Workspace
Make sure you have:
- Clean component state (commit or save current work)
- Mock API ready to modify
- React DevTools open for debugging
Part 1: Implement Pagination
Let's start with pagination - the foundation of this challenge.
Part 2: Add Refresh Functionality
Now implement a manual refresh button that properly handles cleanup.
Part 3: Implement Response Caching
The most challenging part! Cache responses to avoid redundant API calls.
Bonus Challenge 1: Infinite Scroll
Bonus Challenge 2: Search with Debouncing
Bonus Challenge 3: Loading Skeletons
Testing Your Solution
Functionality Testing
Test each feature:
-
Pagination
- Navigate between pages
- Check that listings change
- Verify buttons disable at boundaries
- Check page counter updates correctly
-
Refresh
- Click refresh button
- Verify loading state shows
- Check that data reloads
- Test refresh while on different pages
-
Caching
- Go to page 2, then back to page 1
- Should load instantly from cache
- Wait 5+ minutes, should re-fetch
- Refresh should clear cache
Edge Cases
Test these scenarios:
- Refresh while already loading
- Navigate quickly between pages
- Refresh on last page
- Empty search results
- Network errors during refresh
Performance Check
Use React DevTools:
- No unnecessary re-renders
- Cleanup functions running properly
- No memory leaks (check intervals/listeners)
- Proper AbortController usage
Complete Solution
Try It Yourself First!
Don't peek at the solution until you've attempted the challenge! Learning happens through struggle. If you're stuck, review the hints in each section first.
Code Quality Checklist
Before submitting, verify:
- ✅ No console errors - Clean console output
- ✅ Proper cleanup - All intervals/listeners cleaned up
- ✅ Loading states - User always sees feedback
- ✅ Error handling - All errors caught and displayed
- ✅ AbortController - Requests properly cancelled
- ✅ Cache expiration - Old cache cleared after 5 minutes
- ✅ Accessible UI - Buttons have proper aria-labels
- ✅ Responsive design - Works on mobile/tablet/desktop
- ✅ Code organization - Logic extracted to custom hooks
- ✅ Comments - Complex logic is documented
Reflection Questions
After completing the challenge, consider:
- What was the most challenging part? Why?
- How did custom hooks improve your code? What would it look like without them?
- What edge cases did you discover? How did you handle them?
- How would you test this code? What unit tests would you write?
- What performance improvements could you make? React.memo? useMemo?
Congratulations!
You've completed Module 3! You now have practical experience with:
- ✅ Complex state management
- ✅ Advanced useEffect patterns
- ✅ Custom hooks for reusability
- ✅ Caching and performance optimization
- ✅ Real-world async data handling
These skills form the foundation for building production-ready React applications!
What's Next?
Continue your React journey with Module 4: React Router:
- Learn client-side routing
- Build multi-page applications
- Handle dynamic routes and parameters
- Implement navigation and route protection
You're ready for the next level! 🚀