Projekt: E‑Shop
Březen 2026
Po Pokémon Memory Game přišel další větší milník z The Odin Project – jednoduchý, ale plnohodnotný e‑shop. Cílem nebylo jen něco „naklikat v Reactu“, ale propojit více témat najednou: routing, globální stav (košík), práci s API a moderní UI.
Repozitář projektu: Basic Fake e‑shop
Co projekt dělá
Aplikace simuluje klasický malý e‑shop:
- Zobrazuje produkty z FakeStore API v přehledné mřížce.
- U každého produktu ukazuje název, cenu, kategorii a obrázek.
- Umožňuje přidávat a odebírat položky z košíku.
- Košík je dostupný z každé stránky díky hornímu
Headeru. - Obsahuje základní stránky: Home, Products a Cart.
Technologie a struktura
Projekt běží na:
- Reactu (funkcionální komponenty, hooks),
- Vite pro rychlý vývoj,
- React Router DOM pro navigaci mezi stránkami,
- Tailwind CSS pro rychlé a moderní stylování.
Struktura aplikace je rozdělená na components a pages, podobně jako u větších React projektů:
Header,Footer,Hero,Features– znovupoužitelné komponenty UI.Home,Products,Cart– stránky, které se mění podle URL.
Práce s API a stavem
Produkty se načítají z FakeStore API pomocí fetch/axios a useEffect. Po načtení se uloží do stavu a z nich se renderují karty produktů.
Jednoduché schéma pro načtení produktů může vypadat třeba takto:
useEffect(() => {
const loadProducts = async () => {
try {
const response = await fetch("https://fakestoreapi.com/products");
const data = await response.json();
setProducts(data);
} catch (error) {
console.error("Chyba při načítání produktů:", error);
}
};
loadProducts();
}, []);
Pro košík jsem použil Context API, aby bylo možné z jakékoliv komponenty přidat/odebrat položku a zároveň aktualizovat počet položek v Headeru i obsah stránky Cart:
const CartContext = createContext();
const CartProvider = ({ children }) => {
const [cartItems, setCartItems] = useState([]);
const addToCart = (product) => {
setCartItems((prev) => [...prev, product]);
};
const removeFromCart = (id) => {
setCartItems((prev) => prev.filter((item) => item.id !== id));
};
return (
<CartContext.Provider value={{ cartItems, addToCart, removeFromCart }}>
{children}
</CartContext.Provider>
);
};
Routing a uživatelská zkušenost
Pomocí React Routeru má aplikace klasickou SPA strukturu – stránka se nepřenačítá, mění se jen obsah:
/– úvodní stránka s hero sekcí a základními informacemi o shopu./products– hlavní katalog s produkty z API./cart– přehled košíku s možností položky odebírat.
Header obsahuje odkazy na všechny tři sekce a zároveň ukazuje počet položek v košíku, takže uživatel má neustále přehled, co už přidal.
Co mě potrápilo
- Práce s globálním stavem: Zvyk z menších projektů byl všechno řešit přes
useStatev jedné komponentě. Tady jsem se musel naučit přemýšlet nad tím, co má být globální (košík) a jak to zpřístupnit z různých částí aplikace. - Synchronizace UI a dat: Ujistit se, že UI vždy odráží aktuální stav košíku (např. po odebrání položky z
Cartstránky se ihned aktualizuje i číslo vHeaderu). - Tailwind a design: Tailwind je extrémně rychlý, ale na začátku jsem měl tendenci ztrácet se v nekonečném řetězení tříd. Postupně jsem si ale začal vytvářet konzistentní patterny pro karty, tlačítka a layout.
Co jsem se naučil
- React Router: Jak definovat jednotlivé routy, propojit je s komponentami stránek a jak funguje
<BrowserRouter>,<Routes>a<Route>. - Context API: Jak vytvořit poskytovatele (
Provider), který obalí celou aplikaci, a jak z kontextu číst a zapisovat data v různých komponentách. - Lepší práce s API: Opakování práce s asynchronním kódem, ošetření chyb a zobrazení UI až ve chvíli, kdy jsou data načtená.
- UX e‑shopu: Jak důležité je mít konzistentní layout, viditelné CTA tlačítko „Přidat do košíku“ a okamžitou zpětnou vazbu pro uživatele.
Kam to chci posunout dál
Do budoucna bych chtěl přidat:
- Filtrování podle kategorií a řazení podle ceny.
- Detail produktu na vlastní stránce.
- Uložení košíku do
localStorage, aby nákup „přežil“ obnovení stránky. - Základ falešného checkout flow (rekapitulace objednávky, formulář, potvrzení).
GitHub: Basic Fake e‑shop