A beginner-friendly, production-ready learning app that demonstrates modern React state management using Context API + useReducer with a Vite + TypeScript setup. It helps learners understand how data flows across components, how actions update shared state, and how to build reusable UI modules without Redux.
- Project Overview
- Core Features
- Technology Stack
- Project Architecture
- Project Structure
- Routing & Pages
- State Management Walkthrough
- Components Walkthrough
- How to Run the Project
- Environment Variables (.env)
- Available Scripts
- Dependencies Explained
- Keywords & Concepts
- Code Examples
- How to Reuse in Other Projects
- Backend / API Notes
- Learning Path for Beginners
- Conclusion
This project is a frontend shopping cart application focused on teaching:
- How to model app state with TypeScript types.
- How to manage global state with Context API.
- How to update state predictably with useReducer actions.
- How to build a simple, maintainable React architecture.
It includes two pages (Home and Cart), product listing cards, cart item cards, a sticky navigation header, and educational UI messaging for learning.
- Global state management using React Context API and useReducer
- Add to cart / remove from cart functionality
- Real-time cart total updates
- Typed actions and reducer state (TypeScript)
- Reusable components with isolated CSS files
- Responsive and modern UI sections for beginner learning
- Routing via React Router DOM
- Empty cart educational state with CTA
- Vite: Fast dev server + optimized production bundling.
- React 19: Component-driven UI and hooks.
- TypeScript: Static typing for safer, scalable code.
- React Router DOM 7: Client-side routing (
/and/cart). - Context API + useReducer: Global state and predictable updates.
- ESLint 9 + TypeScript ESLint: Code quality and consistency.
- Custom CSS: Component-level styling and global layout theming.
The app follows a clean layered frontend structure:
- Presentation Layer:
components/andpages/render UI. - State Layer:
context/CartContext.tsxexposes global cart actions/state. - Update Logic Layer:
reducer/cartReducer.tshandles state transitions. - Types Layer:
types/cart.tsdefines Product, State, and Action contracts. - Routing Layer:
routes/AllRoutes.tsxmaps URL paths to page components.
shopmate-context-reducer/
βββ public/
β βββ assets/
β βββ images/
β βββ vite.svg
βββ src/
β βββ components/
β β βββ CartCard.tsx
β β βββ Header.tsx
β β βββ ProductCard.tsx
β β βββ CartCard.css
β β βββ Header.css
β β βββ ProductCard.css
β β βββ index.ts
β βββ context/
β β βββ CartContext.tsx
β βββ hooks/
β β βββ useTitle.ts
β βββ pages/
β β βββ Home.tsx
β β βββ Cart.tsx
β β βββ index.ts
β βββ reducer/
β β βββ cartReducer.ts
β βββ routes/
β β βββ AllRoutes.tsx
β βββ types/
β β βββ cart.ts
β βββ App.tsx
β βββ App.css
β βββ main.tsx
β βββ index.css
βββ index.html
βββ package.json
βββ tsconfig.json
βββ vite.config.ts
βββ README.md/->Home.tsx/cart->Cart.tsx
Route setup is centralized in src/routes/AllRoutes.tsx for easy extension.
CartContext.tsx is the global state gateway.
- Initializes cart state:
cartList: Product[]total: number
- Exposes actions:
addToCart(product)removeFromCart(product)
-
Recalculates totals via
updateTotal(products). -
Dispatches typed reducer actions:
ADD_TO_CARTREMOVE_FROM_CARTUPDATE_TOTAL
cartReducer.ts receives typed actions and returns the next state.
Header.tsx
- Shows app logo/title, route navigation, and live cart count.
ProductCard.tsx
- Renders product info and toggles Add/Remove button based on cart presence.
CartCard.tsx
- Renders selected cart product and supports removal.
Home.tsx
- Provides educational intro, learning panel, and product listing.
Cart.tsx
- Displays cart summary, educational message, and empty-state experience.
git clone https://github.com/arnobt78/Shopping-Cart-Context-Reducer--React-Fundamental-Project-20.git
cd Shopping-Cart-Context-Reducer--React-Fundamental-Project-20This project expects Node 20.x.
npm installnpm run devOpen the local URL shown by Vite (commonly http://localhost:5173).
npm run buildnpm run previewThis project currently does not require any environment variables to run.
- No
.envfile is needed for local development or production build. - No API keys, backend URLs, or secrets are required.
Optional future setup (if you extend this project):
# .env (example for future use)
VITE_APP_TITLE="Shopping Cart Context Reducer"
VITE_API_BASE_URL="https://api.example.com"Important notes:
- In Vite, only variables prefixed with
VITE_are exposed to client code. - Access them using
import.meta.env.VITE_SOME_KEY.
| Script | Purpose |
|---|---|
npm run dev |
Starts Vite development server |
npm run build |
Type checks with TypeScript and builds production assets |
npm run preview |
Serves the built app locally for preview |
npm run lint |
Runs ESLint across the project |
react
- Core UI library for components and rendering.
react-dom
- Bridges React components to the browser DOM.
react-router-dom
- Handles navigation and route rendering.
typescript
- Adds static typing and safer refactoring.
vite and @vitejs/plugin-react
- Fast development startup and optimized production builds.
eslint, @typescript-eslint/*, eslint-plugin-react-hooks, eslint-plugin-react-refresh
- Linting stack for code quality and React hook correctness.
- Context API: Share state across nested components without prop drilling.
- Reducer Pattern: Centralize state transitions using typed action objects.
- Immutable Update: Avoid direct state mutation by returning new objects/arrays.
- Single Source of Truth: Cart state lives in one provider and is consumed everywhere.
- Derived State: Cart total is computed from cart items.
- Custom Hook (
useTitle): Encapsulates repeated page-title logic. - Type Narrowing with Unions: Ensures action safety in reducer switch cases.
export type CartAction =
| { type: "ADD_TO_CART"; payload: { products: Product[] } }
| { type: "REMOVE_FROM_CART"; payload: { products: Product[] } }
| { type: "UPDATE_TOTAL"; payload: { total: number } };createRoot(rootElement).render(
<StrictMode>
<Router>
<CartProvider>
<App />
</CartProvider>
</Router>
</StrictMode>,
);const isInCart = useMemo(() => {
return cartList.some((cartItem) => cartItem.id === id);
}, [cartList, id]);You can reuse this architecture in any small/medium React app:
- Copy
types/cart.tsand adapt the domain models. - Copy
CartContext.tsxand rename to your feature (e.g.,AuthContext). - Copy reducer pattern from
cartReducer.ts. - Replace Product/Cart components with your own UI components.
- Keep actions descriptive and typed for maintainability.
- This is a frontend-only project.
- There is no backend server in this repository.
- There are no API endpoints consumed currently.
- Product data is currently hardcoded in
Home.tsxfor learning simplicity.
If you want to add backend integration later, recommended next step:
- Move product data to an API and fetch it in
Home.tsx. - Keep cart state in context or sync to backend for persistence.
- Run the app and browse
HomeandCartpages. - Read
types/cart.tsfirst to understand data shape. - Read
CartContext.tsxto learn provider/action flow. - Read
cartReducer.tsto understand pure state transitions. - Read
ProductCard.tsxandCartCard.tsxto learn UI-to-state interaction. - Extend with a new feature (quantity, clear cart, or persistence).
- List products with image, name, and price.
- Add/remove products from shared cart state.
- Auto-calculate total amount.
- Show real-time cart count in navbar.
- Show educational empty cart state with CTA.
- Use route-level page titles via custom hook.
src/main.tsx
- App bootstrap, router setup, provider wrapping.
src/context/CartContext.tsx
- Global cart state and cart operations.
src/reducer/cartReducer.ts
- Pure reducer logic for cart actions.
src/pages/Home.tsx
- Product list + educational content.
src/pages/Cart.tsx
- Cart summary, empty-state education, cart item rendering.
src/components/Header.tsx
- Sticky navigation + cart item count.
index.html
- SEO metadata for better discoverability.
- Type-safe state management.
- Single-responsibility modules.
- Reusable components.
- Predictable reducer updates.
- Simple route architecture.
- Build + lint ready project workflow.
This project is a clean educational template for learning modern React fundamentals with TypeScript. It balances practical architecture with beginner-friendly implementation, making it ideal for developers who want to learn Context + Reducer deeply and reuse this pattern in real-world apps.
This project is licensed under the MIT License. Feel free to use, modify, and distribute the code as per the terms of the license.
This is an open-source project - feel free to use, enhance, and extend this project further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://www.arnobmahmud.com.
Enjoy building and learning! π
Thank you! π

