Home > Software design >  How to set different quantity value for every item in online shop using React?
How to set different quantity value for every item in online shop using React?

Time:04-13

I'm trying to make simple online shop using React for learning purposes, but I'm having hard time setting quantity of each item as separate value. Right now I have one variable with works for all three items. Here's some code:

  1. App.js
import { useState } from "react";
import Header from "./Components/Header";
import Cart from "./Components/Cart";
import Shop from "./Components/Shop";
import img1 from "./Pictures/food1.jpg";
import img2 from "./Pictures/food2.jpg";
import img3 from "./Pictures/food3.jpg";

function App() {
  const [showCart, setShowCart] = useState(false);
  const [items, setItems] = useState([
    {
      id: 1,
      name: "Spaghetti",
      price: "300$",
      img: img1,
      alt: "Plate of Spaghetti",
    },
    {
      id: 2,
      name: "Pizza",
      price: "500$",
      img: img2,
      alt: "Pizza",
    },
    {
      id: 3,
      name: "Tiramisu",
      price: "150$",
      img: img3,
      alt: "Tiramisu",
    },
  ]);
  let [quantity, setQuantity] = useState(0);

  const addToCart = () => {
    console.log("Add Value");
    setQuantity((quantity  = 1));
    console.log(quantity);
  };
  const removeFromCart = () => {
    console.log("Lower Value");
    setQuantity((quantity -= 1));
    console.log(quantity);
  };
  return (
    <div className="container">
      <Header onShowCart={() => setShowCart(!showCart)} />
      {showCart && <Cart items={items} quantity={quantity} />}
      <Shop
        items={items}
        onAdd={addToCart}
        onLower={removeFromCart}
        quantity={quantity}
      />
    </div>
  );
}

export default App;
  1. Shop.js (I'm suspecting that I could somehow create those separate values here using .map()
import Item from "./Item";

const Shop = ({ items, onAdd, onLower, quantity }) => {
  return (
    <div className="shop">
      {items.map((item) => (
        <Item
          key={item.id}
          item={item}
          onAdd={onAdd}
          onLower={onLower}
          quantity={quantity}
        />
      ))}
    </div>
  );
};

export default Shop;
  1. Item.js
import React from "react";
import ItemInfo from "./ItemInfo";

const Item = ({ item, onAdd, onLower, quantity }) => {
  return (
    <div className="item">
      <img className="image" src={item.img} alt={item.alt} />
      <ItemInfo
        name={item.name}
        price={item.price}
        onAdd={onAdd}
        onLower={onLower}
        quantity={quantity}
      />
    </div>
  );
};

export default Item;
  1. ItemInfo.js
// import { useState } from "react";
import Button from "./Button";
import ItemNameAndPrice from "./ItemNameAndPrice";

const ItemInfo = ({ name, price, onAdd, onLower, quantity }) => {
  return (
    <div className="info">
      <ItemNameAndPrice name={name} price={price} />
      <div id="buttons-box">
        <Button text={"-"} onClick={onLower} />
        {/* <QuantityOfItems /> */}
        <div className="quantity">{quantity}</div>
        <Button text={" "} onClick={onAdd} />
      </div>
    </div>
  );
};

export default ItemInfo;

5.ItemNameAndPrice.js

import React from "react";

const ItemNameAndPrice = ({ name, price, quantity }) => {
  return (
    <div className="name-and-price">
      <span id="name">{name}</span>
      <span id="price">Price: {price}</span>
      <span>{quantity}</span>
    </div>
  );
};

export default ItemNameAndPrice;

I figured that I could make another component which would store quantity values and operate on them, but in the end I'm remaking the same stuff. Right now this component looks like that:

import { useState } from "react";
const QuantityOfItems = () => {
  let [item1Quantity, setItem1Quantity] = useState(0);
  let [item2Quantity, setItem2Quantity] = useState(0);
  let [item3Quantity, setItem3Quantity] = useState(0);

  return <div>{item1Quantity > 0 && item1Quantity}</div>;
};

export default QuantityOfItems;

Nothing important is here at the moment, because like I've said, I'm hitting a wall here.

Here's how the page looks. The quantity value from App.js is being used inside cart too, but It was made for some testing, so don't pay it much attention.

look of the page

CodePudding user response:

You only have a single quantity state variable in the App component. That means there is only 1 value that you are passing down as a prop to the Item components.

You need to create a separate state variable for each Item. You could do this by including the quantity variable as a piece of the Item's state, like this:

const Item = ({ item, onAdd, onLower }) => {
  let [quantity, setQuantity] = useState(0); // <=== quantity state goes inside the item instead of in the props
  return (
    <div className="item">
      <img className="image" src={item.img} alt={item.alt} />
      <ItemInfo
        name={item.name}
        price={item.price}
        onAdd={() => {
          setQuantity(quantity   1);
        }}
        onLower={() => {
          setQuantity(quantity - 1);
        }}
        quantity={quantity}
      />
    </div>
  );
};

You will then need to change your handler functions slightly to use the Item's setQuantity rather than the App's setQuantity. Note that = and -= are not needed.

  • Related