Home > Enterprise >  how do i get specific data from the state on a button click in react
how do i get specific data from the state on a button click in react

Time:10-18

Here i have 3 products each have it's own addtocart button and it's option like color, size, quantity. so when i click addtocart button after selecting the options it updating the state and giving me exactly i wanted. The problem is when i selelct any product options and then i click on another product addtocart button it shows the selceted option. not the product options of the addtocart button i clicked

for example: i select the 1st product and choose it's options and i did'nt click on the 1st product addtocart button either i clicked 2nd product button but it returns 1st product selected options it should return 2nd product options.

i need to implement which ever the product button i clicks it should only return that product selected options only.it should'nt return any other product selected options.

how do i make this happen. Help me out.

function Card() {
  const [items, setItems] = useState({});

  const handleChageCategory = (key, event) => {
    setItems((oldState) => ({ ...oldState, [key]: event.target.value }));
  };

  const submitHandler = () => {
    console.log(items);
    setItems({});
  };

  return (
    <div className="main-container">
      <div className="container">
        <div className="image-container">
          <img
            src="https://images.pexels.com/photos/9558601/pexels-photo-9558601.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
            alt=""
          />
        </div>
        <h2> T-Shirt </h2>
      </div>
      <div className="form-conatiner">
        <div className="selectors">
          <p>Solid Round Neck T-shirt</p>
          <select
            id="color"
            name="color"
            required
            onChange={(event) => handleChageCategory("color", event)}
          >
            <option>Color</option>
            <option value="black">Black</option>
            <option value="green">Green</option>
            <option value="orange">Orange</option>
          </select>

          <select
            name="quantity"
            required
            onChange={(event) => handleChageCategory("quantity", event)}
          >
            <option>Quantity</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
          </select>

          <select
            name="size"
            required
            onChange={(event) => handleChageCategory("size", event)}
          >
            <option>Size</option>
            <option value="medium">Medium</option>
            <option value="large">Large</option>
            <option value="small">Small</option>
          </select>
          <div>
            <button onClick={submitHandler}>Add to Cart</button>
          </div>
        </div>
      </div>
      {/* second product */}

      <div className="container">
        <div className="image-container">
          <img
            src="https://images.pexels.com/photos/440320/pexels-photo-440320.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
            alt=""
          />
        </div>
        <h2> i-Watch </h2>
      </div>
      <div className="form-conatiner">
        <div className="selectors">
          <p>Dizo watch with amlod </p>
          <select
            id="2"
            name="color"
            required
            onChange={(event) => handleChageCategory("brand", event)}
          >
            <option>Brand</option>
            <option value="Apple">Apple</option>
            <option value="Samsung">Samsung</option>
            <option value="Pixel">Pixel</option>
          </select>

          <select
            name="qantity"
            required
            onChange={(event) => handleChageCategory("qantity", event)}
          >
            <option>Quantity</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
          </select>

          <select
            name="type"
            required
            onChange={(event) => handleChageCategory("type", event)}
          >
            <option>type</option>
            <option value="29mm">29mm</option>
            <option value="34mm">34mm</option>
            <option value="42mm">42mm</option>
          </select>
          <div>
            <button onClick={submitHandler}>Add to Cart</button>
          </div>
        </div>
      </div>
      {/* third product */}
      <div className="container">
        <div className="image-container">
          <img
            src="https://images.pexels.com/photos/1661471/pexels-photo-1661471.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
            alt=""
          />
        </div>
        <h2> Hoodie </h2>
      </div>
      <div className="form-conatiner">
        <div className="selectors">
          <p>Adidas hoodie with zip </p>
          <select
            id="2"
            name="color"
            required
            onChange={(event) => handleChageCategory("color", event)}
          >
            <option>Color</option>
            <option value="Gray">gray</option>
            <option value="White">white</option>
            <option value="Cyan">cyan</option>
          </select>

          <select
            name="qantity"
            required
            onChange={(event) => handleChageCategory("qantity", event)}
          >
            <option>Quantity</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
          </select>

          <select
            name="size"
            required
            onChange={(event) => handleChageCategory("size", event)}
          >
            <option>type</option>
            <option value="39(S)">39(S)</option>
            <option value="42(M)">42(M)</option>
            <option value="46(L)">46(L)</option>
          </select>
          <div>
            <button onClick={submitHandler}>Add to Cart</button>
          </div>
        </div>
      </div>
    </div>
  );
}
export default Card;

CodePudding user response:

A more efficient way to implement a product list is to use a product component for each item which accepts the product data through props. There you will implement all the logic related to the product and check the selected fields and so on.

Full code here.

So here I created Product, which has a selectedValues state that contains the values of all the selectors as an object, and also an handleAddToCart function that sends this product to the parent component function and add the product to the cart there.

Product.js:

const Product = (props) => {
  const [selectedValues, setSelectedValues] = useState({});

  const { name, description, img, selectors } = props;
  //(`selectors` is an array of objects. Each object is a selector with an id field and an array of the `options`).
  
  const handleChangeCategory = (e) => {
    setSelectedValues((prevState) => {
      return { ...prevState, [e.target.name]: e.target.value };
    });
  };

  const handleAddToCart = () => {
    props.addToCart({ name, description, img, selectedValues });//calling the  function from the props.
  };

  return (
    <div className="product">
      <div className="image-container">
        <img width="150px" src={img} alt="" />
      </div>
      <h2> {name}</h2>
      <div className="form-conatiner">
        <p>{description}</p>
        <div className="selectors">
          {selectors.map((s) => {
            return (
              <select
                id={s.id}
                name={s.id}
                required
                onChange={handleChangeCategory}
              >
                {s.options.map((opt) => (
                  <option value={opt}>{opt}</option>
                ))}
              </select>
            );
          })}
        </div>

        <button onClick={handleAddToCart}>Add to Cart</button>
      </div>
    </div>
  );
};
export default Product;

And this is the parent component, where you have the cart and the addToCartHandler function. And in the JSX you simply create a product by calling the Product component and passing the data and the selectors you want to have for this product.

App.js (parent component):

export default function App() {
  //Some dummy cart.
  const DUMMY_CART = [];

  //Function that adds a product to the DUMMY_CART
  const addToCartHandler = (product) => {
    //Do some logic with the cart of course. I'm just pushing it here to show you the result.
     DUMMY_CART.push(product);
     console.log('Added product:', product);
     console.log('Cart:', DUMMY_CART);
  };

  return (
    <div>
      {/* Product 1 */}
      <Product
        img="https://images.pexels.com/photos/9558601/pexels-photo-9558601.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
        name="T-Shirt"
        description="Solid round neck T-Shirt"
        selectors={[
          { id: 'color', options: ['Color', 'blue', 'grin', 'yellow'] },
          { id: 'quantity', options: ['Quantity', 1, 2, 3] },
          { id: 'size', options: ['Size', 'medium', 'large', 'small'] },
        ]}
        addToCart={(product) => addToCartHandler(product)}
      />

      </div>
  );
}

Hope this helps. Please check the full code to see how it works.

CodePudding user response:

const [items, setItems] = useState([]);

The handleChangeCategory Logic

const handleChageCategory = (key,product, event) => {
    const isExist = items.find((item)=>item.id===product.id)
    let updatedItem
    if(isExist){
      updatedItem = {...isExist, [key]: event.target.value}
      setItems((oldState)=>(oldState.map(item=>item.id===updatedItem.id ? updatedItem: item)))
    }else{
      updatedItem = { ...product, [key]: event.target.value };
      setItems((oldState)=>([...oldState, updatedItem]))
    }
  };

Submit handler logic:

const submitHandler = (product) => {
    const isExist = items.find(item=>item.id===product.id)
    const newCartItem = isExist? isExist: product
    console.log(newCartItem);
    setItems((oldState)=>(oldState.filter(item=>item.id!==newCartItem.id)))
  }

I know this is an expensive operation and it might hamper user experience but you wanted to do it this way. To handle add to cart, I think the good way is to open a modal or new page after clicking Add To Cart button that also solves your problem because in this way the user is not able to update one product value and click another product button.

  • Related