August 30, 2023

Goal: A Small Shopping Cart Page

We’ll create:

  1. App: Main component
  2. ProductList: Shows a list of products
  3. ProductItem: One single product
  4. Cart: Shows added items
  5. Use props to pass data, and hooks like useState and useEffect

1. App.js – Main Component

import React, { useState } from "react";
import ProductList from "./ProductList";
import Cart from "./Cart";

function App() {
  const [cartItems, setCartItems] = useState([]);

  const handleAddToCart = (product) => {
    setCartItems((prevItems) => [...prevItems, product]);
  };

  return (
    <div>
      <h1> Pet Store</h1>
      <ProductList onAddToCart={handleAddToCart} />
      <Cart items={cartItems} />
    </div>
  );
}

export default App;

✅ What you learned:

  • cartItems is state (useState)
  • We pass the function handleAddToCart as a prop to child
  • We pass data cartItems to Cart as a prop

2. ProductList.js – List of Products

import React, { useEffect, useState } from "react";
import ProductItem from "./ProductItem";

function ProductList({ onAddToCart }) {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch("https://api.example.com/products")
      .then((response) => {
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        return response.json();
      })
      .then((data) => {
        setProducts(data);
        setLoading(false);
      })
      .catch((error) => {
        setError(error.message);
        setLoading(false);
      });
  }, []);

  return (
    <div>
      <h2>Products</h2>
      {loading && <p>Loading products...</p>}
      {error && <p style={{ color: "red" }}>❌ {error}</p>}
      {!loading && !error && products.map((product) => (
        <ProductItem
          key={product.id}
          product={product}
          onAddToCart={onAddToCart}
        />
      ))}
    </div>
  );
}

export default ProductList;

✅ What you learned:

  • We pass product and onAddToCart as props to ProductItem

3. ProductItem.js – One Product

import React from "react";

function ProductItem({ product, onAddToCart }) {
  return (
    <div style={{ border: "1px solid gray", padding: "10px", margin: "5px" }}>
      <h3>{product.name}</h3>
      <p>Price: ${product.price}</p>
      <button onClick={() => onAddToCart(product)}>Add to Cart</button>
    </div>
  );
}

export default ProductItem;

✅ What you learned:

  • product is a prop (an object with name & price)
  • We call onAddToCart(product) when clicking the button

4. Cart.js – Shopping Cart Component

import React, { useEffect } from "react";

function Cart({ items }) {
  useEffect(() => {
    console.log("Cart updated!", items);
  }, [items]); // Watch the `items` change

  return (
    <div>
      <h2>🛒 Cart</h2>
      {items.length === 0 && <p>No items in cart.</p>}
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item.name} - ${item.price}</li>
        ))}
      </ul>
    </div>
  );
}

export default Cart;

✅ What you learned:

  • useEffect(() => {}, [items]): Runs only when items change
  • Great for doing something like logging, fetching data, or analytics

🔄 Hooks Used

HookWhy we use it
useStateTo manage the cart’s state
useEffectTo react to changes in cart items

🎓 Summary

ConceptExample
Propsproduct, onAddToCart, items
Pass functionPass handleAddToCart from parent to child
useStateStore the cart items
useEffectRun something when data (like items) changes
Multiple componentsApp, ProductList, ProductItem, Cart