Favourites: typed context, a guard hook and a generic list
Build a small favourites app with the patterns from this phase. The starter has two copy-pasted list components and stars that do nothing.
Context: create FavouritesContext with createContext<FavouritesValue | null>(null), where FavouritesValue has ids: string[] and toggle: (id: string) => void. A FavouritesProvider holds the ids in state. A guard hook useFavourites() throws an Error when there is no provider and otherwise returns the value.
Generic list: replace BookList and FilmList with one function List<T> taking items: T[], getId: (item: T) => string and renderLabel: (item: T) => ReactNode. Each <li> shows the label and a <button className="star"> with ★ when the item is a favourite and ☆ when not (also set aria-pressed). Clicking it toggles the favourite.
Keep the ids: the lists are <ul id="books"> and <ul id="films">, and <p id="fav-count"> shows Favourites: <number>.
What Check tests
- Both lists render with a star per item
- Starring a book fills its star and counts it
- Starring a film adds to the same count
- Clicking a filled star removes it, and aria-pressed follows
- Context has a null default and a guard hook that throws
- One generic List<T> replaces the two list components
Stuck? One hint at a time
The solution unlocks after your first Check. Try first: that is where the learning happens.
Your page
Console
Nothing logged yet.