🧩 Week 9 Day 5 Challenges
Challenge 1: Bookmark Manager with Redux Toolkit & Express
Build a bookmark storage app where users can save, tag, and organize their favorite links.
Requirements:
➜ Set up an Express server with GET /api/bookmarks, POST /api/bookmarks, and DELETE /api/bookmarks/:id endpoints. Use an in-memory array (or JSON file) for storage.
➜ Use Redux Toolkit to create a bookmarksSlice with createAsyncThunk for fetching, adding, and deleting bookmarks from your Express backend.
➜ Configure the Redux store with the bookmarks reducer and provide it to your app via <Provider>.
➜ Create a BookmarkList component that uses useSelector and useDispatch to display the bookmarks, show loading/error states, and handle form submission for adding new links.
Challenge 2: Habit Tracker Dashboard with Zustand & LocalStorage Sync
Track daily habits with persistence and a clean dashboard—no backend required for this one, just Zustand plus localStorage.
Requirements:
➜ Create a Zustand store called useHabitStore with state: habits (array), loading (boolean), error (string). Add actions: fetchHabits (reads from localStorage), addHabit, toggleHabit (mark done/undone), and deleteHabit.
➜ Use a custom hook useLocalStorage inside your Zustand actions to sync the habits array to localStorage automatically after every mutation. On initial load, fetchHabits should pull from localStorage.
➜ Use useMemo inside the HabitStats component to calculate the completion rate, current streak, and total active habits without recalculating on every habit toggle.
➜ Use useTransition to mark the habit filter (All / Active / Completed) as a low-priority update, ensuring the toggle buttons remain responsive even with 100 habits.
➜ Use createPortal to render a "Quick Add" modal that floats above the dashboard when the user presses the + button.
Challenge 3: Recipe Finder with RTK Query & Express
Build a recipe discovery app that searches a remote API (or your own Express mock) and caches results intelligently.
Requirements:
➜ Set up an Express server with GET /api/recipes?search=query that returns an array of recipe objects (use a mock dataset or the Spoonacular API).
➜ Use RTK Query's createApi with fetchBaseQuery to define a getRecipes query endpoint and a saveRecipe mutation endpoint for saving favorites.
➜ Use the auto-generated useGetRecipesQuery hook in your SearchPage component. Pass the search term as a query parameter. RTK Query will automatically cache results.
➜ Use useGetRecipesQuery's isFetching and isError flags to show loading spinners and error messages gracefully.
➜ Use useMemo to compute a list of unique recipe categories from the returned data to display as filter chips.
➜ Use useCallback to memoize the search handler that updates the search term state.
➜ Lazy-load the RecipeDetail page using React.lazy and <Suspense> so the user only loads the heavy description and image gallery when they click a recipe.
➜ Use NavLink with active styling to highlight the "Search" and "Favorites" navigation items.
When you are done,
💥 Share your solutions,
💥 invite a friend,
and as always —
💥 stay well, stay curious, and stay coding ✌️
1July 9, 2026 105