This is a production-quality Proof of Concept (POC) demonstrating React Query (TanStack Query) best practices and core concepts through a Library Management System.
- β
Basic query setup with
useQuery - β Query keys and dependency management
- β Query lifecycle (fresh, fetching, stale, inactive)
- β Automatic background refetching
- β Cache deduplication
- β Query invalidation
- β On-Demand Fetching: Manual query triggering
- β Polling: Automatic refetch intervals
- β Dependent Queries: Queries that depend on previous query results
- β Parallel Queries: Multiple queries running simultaneously
- β Pagination: Cursor and page-based pagination
- β Infinite Queries: Infinite scroll implementation
- β Deduplication: Prevents duplicate requests
- β Garbage Collection: Automatic cleanup of unused cache
- β Cache Time: Control cache retention
- β Stale Time: Control when data is considered stale
- β Window Focus Refetching: Re-fetch on window focus
- β Optimistic Updates: Update UI before server confirmation
- β
Basic mutations with
useMutation - β Mutation success/error handling
- β Optimistic updates
- β Cache invalidation after mutations
- β Rollback on error
- β Error boundaries and error handling
- β Loading states and suspense
- β Prefetching
- β Query retries with exponential backoff
- β Request cancellation
- β TypeScript integration
src/
βββ api/
β βββ client.ts # API client configuration
β βββ books.api.ts # Books API endpoints
β βββ reviews.api.ts # Reviews API endpoints
β βββ users.api.ts # Users API endpoints
βββ hooks/
β βββ queries/
β β βββ useBooks.ts # Book-related queries
β β βββ useReviews.ts # Review queries
β β βββ useUsers.ts # User queries
β βββ mutations/
β βββ useBookMutations.ts # Book mutations
β βββ useReviewMutations.ts # Review mutations
βββ types/
β βββ book.types.ts # Book-related types
β βββ review.types.ts # Review types
β βββ api.types.ts # API response types
βββ components/
β βββ books/ # Book-related components
β βββ reviews/ # Review components
β βββ common/ # Shared components
β βββ layout/ # Layout components
βββ pages/
β βββ Books.tsx # Books listing page
β βββ BookDetail.tsx # Book detail page
β βββ Reviews.tsx # Reviews page
β βββ Dashboard.tsx # Dashboard with stats
βββ utils/
β βββ queryClient.ts # Query client configuration
β βββ helpers.ts # Utility functions
βββ App.tsx # Main app component
βββ main.tsx # Entry point
- Node.js 18+
- npm or yarn
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview- View all books with pagination
- Search and filter books
- View book details with reviews
- Check book availability
- Checkout/return books
- View reviews for books
- Add new reviews
- Edit/delete reviews (optimistic updates)
- Real-time review updates
- Latest activity across the library
- Polling for new activities
- Activity filters
- Instant search with debouncing
- Search across books, authors, and genres
// Hierarchical query keys for easy invalidation
['books'] // All books
['books', { page: 1 }] // Books page 1
['books', bookId] // Specific book
['books', bookId, 'reviews'] // Book reviews// Only fetch reviews after book data is loaded
const { data: book } = useBook(bookId);
const { data: reviews } = useBookReviews(bookId, {
enabled: !!book,
});// Update UI immediately, rollback on error
mutate(newData, {
onMutate: async (newData) => {
// Cancel outgoing refetches
await queryClient.cancelQueries({ queryKey: ['books'] });
// Snapshot previous value
const previous = queryClient.getQueryData(['books']);
// Optimistically update
queryClient.setQueryData(['books'], (old) => [...old, newData]);
return { previous };
},
onError: (err, newData, context) => {
// Rollback on error
queryClient.setQueryData(['books'], context.previous);
},
});const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery({
queryKey: ['books', 'infinite'],
queryFn: ({ pageParam = 0 }) => fetchBooks(pageParam),
getNextPageParam: (lastPage) => lastPage.nextCursor,
});const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
gcTime: 1000 * 60 * 30, // 30 minutes (formerly cacheTime)
refetchOnWindowFocus: true,
refetchOnReconnect: true,
retry: 3,
retryDelay: (attemptIndex) =>
Math.min(1000 * 2 ** attemptIndex, 30000),
},
},
});The POC includes a complete mock API that simulates:
- Network delays
- Error scenarios
- Pagination
- Search functionality
- CRUD operations
The UI is intentionally simple and functional to keep focus on React Query implementation patterns. The emphasis is on:
- Clean, maintainable code
- Proper error handling
- Loading state management
- TypeScript type safety
- Production-ready patterns
Each component includes detailed comments explaining:
- Why specific React Query options are used
- How the query/mutation works
- Best practices being followed
- Common pitfalls to avoid
This POC is designed as a reference implementation. Feel free to:
- Extend with additional features
- Add more complex query patterns
- Improve UI/UX
- Add tests
MIT
Based on "The Official React Query Course" by ui.dev