Product Filter
Fetch a product catalog from a REST API, then let the user narrow it down with a category dropdown and a debounced search box. Both filters combine, and the visible list is derived from the source data — never stored separately. Uses the Fake Store API.
Requirements
- Fetch all products once on mount; handle loading and error states
- Build the category dropdown dynamically from the fetched data (plus an "All" option)
- Selecting a category filters the list
- A search box filters by title, debounced (~300ms) so it does not filter on every keystroke
- Category + search filters apply together
- Show a "no products match" empty state
- Show a live count of visible products
- Keep styling minimal — the focus is the data flow and state, not visual polish
Key Patterns
visible list = useMemo over (allProducts, category, debounced) — derived, not storeddebounce: useEffect mirrors search → debounced via setTimeout, cleared on each keystrokederive categories with [...new Set(products.map(p => p.category))]one request status (loading | success | error) instead of parallel flags
Important
Interview Tip
The trap is storing a separate `filteredProducts` state and writing to it inside the change handlers — two sources of truth that drift apart. Instead derive the visible list with useMemo from (data, category, debouncedSearch). For the debounce, keep the raw input value in `search` for a responsive field, and mirror it into `debounced` via a useEffect + setTimeout whose cleanup clears the pending timer — filtering reads only `debounced`. Derive categories from the data so the dropdown stays in sync automatically.
Loading…