Create shopping cart using Context api (useContext)

Folder - src/components :
---------------------------

Source Code Link - https://github.com/highhimanshu/shoppingcart-useContext

Cart.js:
import React, { useState, useEffect, useContext } from 'react';
import SingleProduct from './SingleProduct';
import { C } from '../Context';

const Cart = () => {
  const { cart } = useContext(C);

  const [totalPrice, setTotalPrice] = useState(0);

  console.log(cart);

  function addingPrice() {
    setTotalPrice(cart.reduce((acc, ele) => acc + Number(ele.price), 0));
  }

  useEffect(() => {
    addingPrice();
  }, [cart]);

  return (
    <>
      <span>Total Product Added - {cart.length}</span>
      <br />
      <span>Total - $ {totalPrice} </span>
      <div className="productContainer">
        {cart.map(prod => (
          <SingleProduct p={prod} key={prod.id} />
        ))}
      </div>
    </>
  );
};

export default Cart;



Header.js:

import React, { useContext } from 'react';
import { Link } from 'react-router-dom';
import './Header.css';
import { C } from '../Context';

const Header = () => {
  const { cart } = useContext(C);

  return (
    <>
      <span className="header">Header Component </span>
      <ul className="nav">
        <li className="header1">
          <Link to="/"> Home Page</Link>
        </li>
        <li className="header2">
          <Link to="/cart"> Cart ({cart.length}) </Link>
        </li>
      </ul>
    </>
  );
};

export default Header;


Header.css

.header {
  display: block;
  text-align: center;
  font-weight: bold;
  font-size: 1.5rem;
  margin: 10px;
}

.nav {
  display: flex;
  list-style: none;
  justify-content: space-around;
  align-items: center;
  background-color: brown;
  padding-top: 20px;
  padding-bottom: 20px;
}

.nav > li {
  color: white;
  font-size: 17px;
  cursor: pointer;
}
.nav > li :hover {
  color: rgb(224, 202, 202);
}


Home.js

import React, { useState, useContext } from 'react';
import SingleProduct from './SingleProduct';
import faker from 'faker';
import './Home.css';
import { C } from '../Context';

faker.seed(100);

const Home = () => {
  const productArray = [...Array(20)].map(() => ({
    id: faker.datatype.uuid(),
    name: faker.commerce.productName(),
    price: faker.commerce.price(),
    image: faker.random.image()
  }));

  const [products, setProducts] = useState(productArray);

  return (
    <>
      <div className="productContainer">
        {products.map(prod => {
          return <SingleProduct p={prod} />;
        })}
      </div>
    </>
  );
};

export default Home;



Home.css

.productContainer {
  display: flex;
  padding: 20px;
  flex-wrap: wrap;
  justify-content: space-evenly;
}

.products {
  width: 25%;
  display: flex;
  flex-direction: column;
  padding: 10px;
  margin: 15px;
  border: 1px solid red;
}

.productDesc {
  display: flex;
  padding-top: 5px;
  justify-content: space-between;
}

.cart-btn {
  padding: 5px;
  margin: 10px;
}



SingleProduct.js

import React, { useContext } from 'react';
import { C } from '../Context';

const SingleProduct = ({ p }) => {
  const { cart, setCart } = useContext(C);

  function addToCart() {
    setCart([...cart, p]);
  }

  function removeFromCart() {
    setCart(cart.filter(c => c.id !== p.id));
  }

  return (
    <>
      <div class="products">
        <img src={p.image} alt={p.name} />
        <div className="productDesc">
          <span>{p.name}</span>
          <span>$ {p.price.substring(0, 3)}</span>
        </div>
        {cart.includes(p) ? (
          <button className="cart-btn" onClick={removeFromCart}>
            Remove from cart
          </button>
        ) : (
          <button className="cart-btn" onClick={addToCart}>
            Add to Cart
          </button>
        )}
      </div>
    </>
  );
};

export default SingleProduct;



Folder - src :
-------------------------------

App.js

import React, { useState } from 'react';
import Header from './components/Header';
import Home from './components/Home';
import Cart from './components/Cart';
import { BrowserRouter, Route } from 'react-router-dom';
import './style.css';

export default function App() {
  return (
    <BrowserRouter>
      <Header />

      <Route exact path="/">
        <Home />
      </Route>
      <Route path="/cart">
        <Cart />
      </Route>
    </BrowserRouter>
  );
}



Context.js

import React, { createContext, useState } from 'react';

export const C = createContext();

const Context = ({ children }) => {
  const [cart, setCart] = useState([]);
  return <C.Provider value={{ cart, setCart }}>{children}</C.Provider>;
};

export default Context;


index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Context from './Context';

import App from './App';

ReactDOM.render(
  <Context>
    <App />
  </Context>,
  document.getElementById('root')
);



style.css

* {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

a {
  text-decoration: none;
  color: inherit;
}










1 Comments

  1. You are one of the few who produce shopping cart using only useContext hook. I was looking for it and found it here. Most of the tubes are useContext and useReducer. Thanks for this really appreciate.

    ReplyDelete