- Favorites — the list of crypto IDs the user has saved
- Color mode — whether the UI is in dark or light mode
src/context/useContext.jsx. Each context is created, provided, and consumed through a dedicated hook, keeping component code clean.
FavoritesProvider and useFavorites
FavoritesProvider delegates its state logic entirely to the useFavorites hook from src/hooks/useFavorites.jsx. The hook manages an array of saved coin IDs, persists it to localStorage, and exposes four values to consumers.
localStorage so favorites survive page refreshes without a separate effect on mount.
Context values exposed by useFavorites
| Value | Type | Description |
|---|---|---|
favorites | string[] | Array of saved coin IDs (e.g. ["bitcoin", "ethereum"]) |
addFavorite(cryptoId) | function | Appends a coin ID to the favorites list |
removeFavorite(cryptoId) | function | Removes a coin ID from the favorites list |
isFavorite(cryptoId) | function | Returns true if the coin ID is in the list |
FavoritesProvider passes the entire object returned by useFavorites as the context value:
useFavorites() gets the full { favorites, addFavorite, removeFavorite, isFavorite } object.
ColorModeProvider and useColorMode
ColorModeProvider manages a single boolean darkMode and a toggle function. It also persists the preference to localStorage and applies or removes the dark class on <html> so Tailwind’s dark-mode utilities take effect.
How dark mode works
Preference restored on mount
The first
useEffect (empty dependency array) reads localStorage.getItem("saveMode"). If it equals the string "true", darkMode is set to true.Class toggled on change
The second
useEffect runs whenever darkMode changes. It adds the dark class to document.documentElement (<html>) when enabled and removes it when disabled.Preference persisted
The same effect writes the current value back to
localStorage under the key saveMode, so the choice survives a page reload.Context values exposed by useColorMode
| Value | Type | Description |
|---|---|---|
darkMode | boolean | true when dark mode is active |
changeColorMode | function | Toggles darkMode between true and false |
Provider nesting in App.jsx
Both providers wrap the entire component tree insideApp, so every route and every component can access either context without prop drilling.
FavoritesProvider is the outer wrapper because it has no dependency on color mode. ColorModeProvider is nested inside it. Navbar and all page components are children of both, meaning a single call to useFavorites() or useColorMode() inside any of them resolves to the correct context value.