🛍️ Building a React Shopping Cart Site: Lessons Learned from Real Challenges

Shumaila SayedShumaila Sayed
4 min read

Creating a fully functional shopping cart application with React was more than just a practice project, it was a deep dive into real-world development problems, state management, component design, and deployment strategies.

In this post, I’ll walk you through how I approached the project, the technical decisions I made, the custom tools I built (like a custom hook for quantity), and what I learned along the way.


Project Overview

This project was designed to simulate a basic e-commerce experience. The main features included:

  • A Home page, Shop page and a Cart page with routing between them

  • A responsive navigation bar shared across both pages

  • Product listings fetched from the FakeStore API

  • A fully interactive cart system with quantity selection

  • A badge in the navbar showing the number of items in the cart

  • Proper state updates when items are added/removed

  • Deployment as a single-page application (SPA)

  • Custom hook for managing product quantity

  • Testing using React Testing Library and Vitest


Creating a Custom Hook for Quantity Management

One of the standout decisions in this project was abstracting the quantity logic into a custom hook.

Instead of repeating useState, onChange, increment, and decrement logic across every product card, I created a hook like this:

import { useState } from 'react';

const useCartQuantity = (product, cartList, setCartList) => {
    const [quantity, setQuantity] = useState(product.quantity || 1);

    const updateQuantity = (newQuantity) => {
        setQuantity(newQuantity);
        const updatedCart = cartList.map((item) =>
            item.id === product.id ? { ...item, quantity: newQuantity } : item
        );
        setCartList(updatedCart);
    };

    const incrementQuantity = (e) => {
        e.preventDefault();
        updateQuantity(quantity + 1);
    };

    const decrementQuantity = (e) => {
        e.preventDefault();
        if (quantity > 1) {
            updateQuantity(quantity - 1);
        }
    };

    return {
        quantity,
        setQuantity,
        updateQuantity,
        incrementQuantity,
        decrementQuantity,
    };
};

export default useCartQuantity;

Using this hook simplified my product card component and improved code readability and reusability.


Managing Cart State Across Components

Cart state management became a little tricky as it had to be:

  • Updated when items are added or modified

  • Shared between multiple components (product cards, navbar badge, cart page)

  • Reflect real-time updates like quantity changes

I used useState and React context (or optionally a state management library like Redux) to lift the cart state to a higher-level component so it could be accessed and modified globally.


Fetching Data from the FakeStore API

To keep the app dynamic, I used the FakeStore API to fetch product data. Here’s a basic example:

useEffect(() => {
  const fetchProducts = async () => {
    try {
      const res = await fetch('https://fakestoreapi.com/products');
      const data = await res.json();
      setProducts(data);
    } catch (error) {
      console.error('Error fetching products:', error);
    }
  };
  fetchProducts();
}, []);

This taught me how to gracefully handle loading and error states while ensuring the UI stays responsive.


Writing Tests with React Testing Library

Testing was another valuable part of this project. I used React Testing Library to:

  • Simulate user interactions (clicks, input changes)

  • Assert changes in the DOM (cart updates, page content)

  • Avoid testing third-party libraries like react-router-dom directly

Example test for the cart count:

it('calculates and displays correct cart quantity', () => {
        const mockCartList = [
            { id: 1, title: 'Product 1', quantity: 2 },
            { id: 2, title: 'Product 2', quantity: 3 },
        ];

        render(
            <MemoryRouter>
                <Navbar cartList={mockCartList} />
            </MemoryRouter>
        );

        expect(screen.getByText('5')).toBeInTheDocument();
    });

Deploying as a Single Page App on Vercel

Once development was complete, I deployed the app to Vercel. But I ran into an issue: refreshing non-root routes resulted in a 404 error. That’s because SPAs need to serve index.html for all routes.

To fix this, I added a vercel.json file at the root of my project:

{
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/index.html"
    }
  ]
}

Now Vercel knows to let React Router handle routing client-side.


Styling & User Experience

I kept the styling clean and user-friendly using a combination of CSS modules and utility classes. Each product card included:

  • Product image and title

  • Input field for quantity

  • Increment/decrement buttons

  • “Add to Cart” button

The navigation bar showed the current cart count and a link to view the cart for checkout.


What I Learned

Building this shopping cart project was a fantastic learning experience. Here's a quick summary of key takeaways:

  • Creating custom hooks improves code reusability and cleanliness

  • Lifting state up and managing it globally is essential for dynamic UIs

  • Deployment for SPAs requires route rewriting on platforms like Vercel

  • Testing user flows is better than testing implementation details

  • Styling and small UX touches really elevate the app's experience


Try it Out

đź”— Live Demo: https://affordrobe.vercel.app/
đź’» GitHub Repo: https://github.com/Shumaila-sayed/Affordrobe


Final Thoughts

If you’re learning React and want a project that puts your knowledge to the test, building a shopping cart is a perfect choice. You’ll touch nearly every key React concept: state, props, routing, custom hooks, API calls, testing, and deployment.

Let me know if you give it a try or want to collaborate on something similar!


#ReactJS #WebDevelopment #CustomHooks #WomenWhoCode #FrontendDevelopment #OpenToWork #Vercel #JavaScript #ReactTestingLibrary

0
Subscribe to my newsletter

Read articles from Shumaila Sayed directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Shumaila Sayed
Shumaila Sayed

On a journey to learn coding and contribute to open source.🥂 📌Currently learning Responsive web design