Implementing an E-Commerce "Add to Cart" Feature in React: A Step-by-Step Guide
Published: 2024-01-22 13:07:46

**Introduction**
The world of e-commerce has witnessed a tremendous surge in recent years, and building a seamless shopping experience is crucial for the success of any online store. One of the fundamental features in any e-commerce application is the "Add to Cart" functionality, allowing users to easily select and store items they wish to purchase. In this blog, we will explore how to implement the "Add to Cart" feature using React, a popular JavaScript library for building user interfaces.

**Prerequisites**
Before diving into the implementation, make sure you have Node.js and npm (Node Package Manager) installed on your machine. You can create a new React application using Create React App:

```bash
npx create-react-app ecommerce-cart
cd ecommerce-cart
npm start

```
Now, let's start implementing the "Add to Cart" functionality.

Step 1: Set Up the Project Structure
Organize your project by creating a dedicated folder structure. For simplicity, let's create a 'components' folder to store our React components.

```javascript
src
|-- components
|   |-- AddToBasketList.js
|   |-- Basket.js
|   |-- BasketItem.js
|   |-- BasketCard.js
|   |-- TotalPrice.js
|-- context
|   |-- CartContext.js

```

Step 2: Create Product and Cart Components
In Basket.js, create a list of products that users can add to their shopping cart:

```javascript
import React from 'react';
import basketData from '../data.js/basketData';
import BankCard from './BankCard';
import BasketCard from './BasketCard';
import SlideCarousel from './Carousel';
import CategoryList from './CategoryList';
import DailyStapleCard from './DailyStapleCard';
import GroceryText from './GroceryText';

function Basket() {
    return (
        <>
            <div className='container custom-container'>
                <div className='row'>
                    <div className='header-category d-flex w-100'>
                        <CategoryList />
                    </div>

                    <div className='col-lg-12 my-4 discounted-img'>
                        <img src="https://source.unsplash.com/300x200/?grapes" className='img-fluid w-100' alt="discount show" style={{height: "250px", borderRadius: "20px"}} />
                        <span className='text-on-discounted-img text-center'>
                            <p className='m-0 p-0'>Upto</p>
                            <p className='m-0 p-0'>20%</p>
                        </span>
                    </div>

                    <h1>My Smart Basket</h1>

                    {basketData.slice(0,8).map((item) => (
                        <BasketCard item={item} key={item.id} />
                    ))}

                    

                </div>
            </div>
        </>
    )
}

export default Basket;

```

assume you have a list of basketData like

```javascript
const basketData = [
    {
        id: 1,
        imgSrc: "https://source.unsplash.com/300x200/?banana",
        category: "Fresh",
        name: "Banana",
        amount: "1kg",
        discounted_price: "59.13",
        actual_price: "81",
        sale: "Get it for just ₹56.17!",
        off_on_product: "27",
        count: 1,
    },
];
export default basketData;

```
### AddToBasketList.js

```javascript
import React, { useEffect, useState } from 'react';
import { useCart } from '../context/CartContext';
import BasketItem from './BasketItem';
import TotalPrice from './TotalPrice';

function AddToBasketList() {
  const { cartItems, removeFromCart,totalPrice } = useCart();

  const handleDeleteItem = (deletedItem, deletedPrice) => {
    removeFromCart(deletedItem, deletedPrice);
  };  

  return (
    <>
      <div className="container custom-container mb-5">
        <p className='mt-3'>My Basket</p>

        {cartItems.map((item, index) => (
          <BasketItem 
          index={index} 
          key={index} 
          item={item} 
          onDelete={(deletedItem, deletedPrice) => handleDeleteItem(deletedItem, deletedPrice)}  />
        ))}        

        <TotalPrice />
      </div>
    </>
  )
}

export default AddToBasketList;

```

### BasketCard.js

```javascript
import React from 'react';
import { Link } from 'react-router-dom';
import { useCart } from '../context/CartContext';

function BasketCard({ item }) {
  const { addToCart } = useCart();

  const handleAddToCartClick = (item) => {
    addToCart(item, item.discounted_price);
  };

  return (
    <>
      <div className="col-lg-3 item-card" key={item.id}>
        <div className='shadow'>
          <div className="card mb-4 p-2">
            <Link to={`/details/${item.id}`}>
            <img src={item.imgSrc} className="card-img-top" alt="bigbasket item" />
            </Link>
            <span className='off_on_product bg-success p-2'>{item.off_on_product}% OFF</span>
            <div className="card-body">
              <p className="text-sm">{item.category}</p>
              <h5 className="card-title">{item.name}</h5>
              <div className="mb-3">
                <label htmlFor="exampleSelect" className="form-label">Select an option:</label>
                <select className="form-select" id="exampleSelect">
                  <option value="" >{item.amount}</option>
                  <option value="option1">Option 1</option>
                  <option value="option2">Option 2</option>
                  <option value="option3">Option 3</option>
                </select>
              </div>
              <h5 className="card-title">₹{item.discounted_price} <span className='text-decoration-line-through'>₹{item.actual_price}</span></h5>

              <div className="mb-3">
                <label htmlFor="exampleSelect" className="form-label">Select an option:</label>
                <select className="form-select" id="exampleSelect">
                  <option value="">{item.sale}</option>
                  <option value="option1">Option 1</option>
                  <option value="option2">Option 2</option>
                  <option value="option3">Option 3</option>
                </select>
              </div>

              <div className="d-flex">
                <span className='p-1 px-2 border me-2' title='Add to Fav'>
                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-bookmark" viewBox="0 0 16 16">
                    <path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v13.5a.5.5 0 0 1-.777.416L8 13.101l-5.223 2.815A.5.5 0 0 1 2 15.5zm2-1a1 1 0 0 0-1 1v12.566l4.723-2.482a.5.5 0 0 1 .554 0L13 14.566V2a1 1 0 0 0-1-1z" />
                  </svg>
                </span>
                <span className='w-100'>
                  <button className='btn btn-outline-danger w-100' onClick={() => handleAddToCartClick(item)}>Add</button>
                </span>
              </div>

            </div>
          </div>
        </div>
      </div>
    </>
  )
}

export default BasketCard;

```

### BasketItem.js

```javascript
import React, { useEffect } from 'react';
import { useState } from 'react';
import { useCart } from '../context/CartContext';

function BasketItem({ onDelete, item, index, getCount, updateTotalPrice }) {
  let previousCount = JSON.parse(localStorage.getItem(`cartCount_${index}`)) || 1;
  let [count, setCount] = useState(previousCount);
  let { setTotalPrice } = useCart();


  useEffect(() => {
    localStorage.setItem(`cartCount_${index}`, JSON.stringify(count));
  }, [count, index]);


  let discountedPrice = (item.discounted_price * count).toFixed(2);
  let actualPrice = (item.actual_price * count).toFixed(2);
  let savePrice = (actualPrice - discountedPrice).toFixed(2);

  if (count < 1) {
    alert("You can't select 0 Item")
    count = 1
    discountedPrice = (item.discounted_price * count).toFixed(2);
    savePrice = (item.actual_price - item.discounted_price).toFixed(2);
  }

  const handleDelete = () => {
    onDelete(item, discountedPrice);
  };

  const handleIcrCount = (index) => {
    setCount(() => {
      const updatedCounts = count + 1
      setTotalPrice((prevTotalPrice) => prevTotalPrice + (item.discounted_price * 1));
      localStorage.setItem(`cartCount_${index}`, JSON.stringify(updatedCounts));
      return updatedCounts;
    });
  };

  const handleDcrCount = (index) => {
    setCount(() => {
      const updatedCounts = count - 1
      setTotalPrice((prevTotalPrice) => prevTotalPrice - (item.discounted_price * 1));
      localStorage.setItem(`cartCount_${index}`, JSON.stringify(updatedCounts[index]));
      return updatedCounts;
    });
  };

  return (
    <>
      <div className="add-to-card card mb-1">
        <div className="card-body d-flex">
          <div className="card-img d-flex justify-content-between align-items-center">
            <div className='border'>
              <img src={item.imgSrc} alt="card image" className='img-fluid' style={{ maxWidth: '100px' }} />

            </div>
            <div className='title'>
              <p className='text-muted'>{item.category} {index}</p>
              <p className='name'>{item.name} 1 kg</p>
              <p className='text-muted'>1 x 80.00</p>
            </div>
            <div className='d-flex amount'>
              <span onClick={handleDcrCount}>
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-dash border rounded-circle" viewBox="0 0 16 16">
                  <path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8" />
                </svg>
              </span>
              <p className='mx-2 count'>{count}</p>
              <span onClick={handleIcrCount}>
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-plus border rounded-circle" viewBox="0 0 16 16">
                  <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4" />
                </svg>
              </span>
            </div>
            <div className='price'>
              <p>Rs. {discountedPrice}</p>
              <p className='text-success'>Save Rs. {savePrice}</p>
            </div>
            <div className='cross' onClick={handleDelete}>
              <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="currentColor" className="bi bi-file-x" viewBox="0 0 16 16">
                <path fillRule="evenodd" d="M6.146 6.146a.5.5 0 0 1 .708 0L8 7.293l1.146-1.147a.5.5 0 1 1 .708.708L8.707 8l1.147 1.146a.5.5 0 0 1-.708.708L8 8.707 6.854 9.854a.5.5 0 0 1-.708-.708L7.293 8 6.146 6.854a.5.5 0 0 1 0-.708" />
              </svg>

            </div>

          </div>
        </div>
      </div>
    </>
  )
}

export default BasketItem;

```

### TotalPrice.js

```javascript
import React from 'react';
import { useCart } from '../context/CartContext';

function TotalPrice() {
  const { totalPrice } = useCart();
    
  return (
    <>
        <div className='d-flex justify-content-end text-align-center align-items-center my-auto'>
        <div>
          <div className='d-flex justify-content-between mt-3'>
            <p>Total</p>
            <p>:</p>
            <p>{`Rs. ${totalPrice.toFixed(2)}`}</p>
          </div>
          <p className='line'></p>
          <div className='d-flex justify-content-end'>
            <button className='btn btn-dark'>Pay Now</button>
          </div>

        </div>
        </div>
    </>
  )
}

export default TotalPrice;

```

### context file CartContext.js

```javascript
import React, { createContext, useContext, useEffect, useState } from 'react';

const CartContext = createContext();

export const CartProvider = ({ children }) => {
  const storedCartItems = JSON.parse(localStorage.getItem('cartItems')) || [];
  const storedPrice = JSON.parse(localStorage.getItem('cartItems_price'));
  const [cartItems, setCartItems] = useState(storedCartItems);
  let [totalPrice, setTotalPrice] = useState(storedPrice);

  const addToCart = (item, discounted_price) => {
    setCartItems((prevItems) => [...prevItems, item]);
    setTotalPrice(totalPrice + parseFloat(discounted_price));
  };

  const removeFromCart = (item, price) => {
    const updatedCartItems = cartItems.filter((cartItem) => cartItem.id !== item.id);
    setCartItems(updatedCartItems);

    setTotalPrice(totalPrice - price);
  };

  
  useEffect(() => {
    localStorage.setItem('cartItems', JSON.stringify(cartItems));
  }, [cartItems]);

  useEffect(() => {
    localStorage.setItem('cartItems_price', JSON.stringify(totalPrice));
  }, [totalPrice]);

  console.log('storedPrice', storedPrice)
  return (
    <CartContext.Provider value={{ cartItems, addToCart, removeFromCart,totalPrice, setTotalPrice }}>
      {children}
    </CartContext.Provider>
  );
};

export const useCart = () => {
  const context = useContext(CartContext);
  if (!context) {
    throw new Error('useCart must be used within a CartProvider');
  }
  return context;
};

```


That's it.
Congratulations! You've successfully implemented the "Add to Cart" functionality in a React application. 

Happy coding!🚀