Home > Net >  Is there a way to only target one button in the React map?
Is there a way to only target one button in the React map?

Time:07-30

I am trying to make only one button in my React map method interactive. but when I click on one of them, they both react. I would like to target only one button.Kindly assist

import React, { useEffect, useState } from "react";

function Women() {
  const [womenShoes, setWomenShoes] = useState([]);
  const [count, setCount] = useState(0);
  const [addToCart, setAddToCart] = useState(true);

  const addItems = () => {
    setCount(count   1);
    setAddToCart(!addToCart);
  };

  useEffect(() => {
    fetch("https://pacific-leaf-twig.glitch.me/women-shoes")
      .then((response) => response.json())
      .then((data) => setWomenShoes(data));
  }, []);

  return (
    <div className="d-flex flex-wrap justify-content-center gap-5 mt-5">
      {womenShoes.map((shoe, index) => (
        <div key={index} className="card mt-5" style={{ width: "25rem" }}>
          <img src={shoe.img} className="card-img-top img-fluid" alt="A shoe" />
          <div className="card-body d-flex">
            <div>
              <h5 className="card-title">{shoe.name}</h5>
              <p className="card-text">{`Items Remaining ${shoe.itemsLeft}`}</p>
              <button onClick={addItems} className="btn btn-primary">
                {addToCart ? "Add to Cart" : "Remove from the Cart"}
              </button>
            </div>
            <div className="mx-auto align-self-center">
              <h4>{`$ ${shoe.price}`}</h4>
            </div>
          </div>
        </div>
      ))}
      <div className="counter">{`Items: ${count}`}</div>
    </div>
  );
}

export default Women;

CodePudding user response:

You need to make a separate component for the button in order for it to have its own state. Here's a quick draft showing the changes:

import React, { useEffect, useState } from 'react'
import ReactDOM from 'react-dom'

/* Button component with its own state. */
function AddButton({addItems}) {
  const [addToCart, setAddToCart] = useState(true);

  function addItem(){
    addItems();
    setAddToCart(!addToCart);
  }
  
  return (
    <button onClick={addItem} className="btn btn-primary">
      {addToCart ? "Add to Cart" : "Remove from the Cart"}
    </button>
  )
}

function Women() {
  const [womenShoes, setWomenShoes] = useState([]);
  const [count, setCount] = useState(0);

  const addItems = () => {
    setCount(count   1);
  };

  useEffect(() => {
    fetch("https://pacific-leaf-twig.glitch.me/women-shoes")
      .then((response) => response.json())
      .then((data) => setWomenShoes(data));
  }, []);

  return (
    <div className="d-flex flex-wrap justify-content-center gap-5 mt-5">
      {womenShoes.map((shoe, index) => (
        <div key={index} className="card mt-5" style={{ width: "25rem" }}>
          <img src={shoe.img} className="card-img-top img-fluid" alt="A shoe" />
          <div className="card-body d-flex">
            <div>
              <h5 className="card-title">{shoe.name}</h5>
              <p className="card-text">{`Items Remaining ${shoe.itemsLeft}`}</p>
              <AddButton addItems={addItems}/>
            </div>
            <div className="mx-auto align-self-center">
              <h4>{`$ ${shoe.price}`}</h4>
            </div>
          </div>
        </div>
      ))}
      <div className="counter">{`Items: ${count}`}</div>
    </div>
  );
}

ReactDOM.render(
  <Women />,
  document.getElementById('container')
);

CodePudding user response:

You need to handle the cart state separately. Following will keep an array of selected cart items. You can extend it to handle available counts and add multiple items of the same item.

function Women() {
  const [womenShoes, setWomenShoes] = React.useState([]);
  const [cart, setCart] = React.useState([]);

  const isSelectedItem = (itemId) => cart.indexOf(itemId) >= 0;

  const addItems = (itemId) => {
    setCart((prevItems) =>
      isSelectedItem(itemId)
        ? prevItems.filter((item) => item !== itemId)
        : [...prevItems, itemId]
    );
  };

  React.useEffect(() => {
    fetch("https://pacific-leaf-twig.glitch.me/women-shoes")
      .then((response) => response.json())
      .then((data) => setWomenShoes(data));
  }, []);

  return (
    <div className="d-flex flex-wrap justify-content-center gap-5 mt-5">
      {womenShoes.map((shoe, index) => (
        <div key={index} className="card mt-5" style={{ width: "25rem" }}>
          <img src={shoe.img} className="card-img-top img-fluid" alt="A shoe" />
          <div className="card-body d-flex">
            <div>
              <h5 className="card-title">{shoe.name}</h5>
              <p className="card-text">{`Items Remaining ${shoe.itemsLeft}`}</p>
              <button
                onClick={() => addItems(shoe.id)}
                className="btn btn-primary"
              >
                {!isSelectedItem(shoe.id)
                  ? "Add to Cart"
                  : "Remove from the Cart"}
              </button>
            </div>
            <div className="mx-auto align-self-center">
              <h4>{`$ ${shoe.price}`}</h4>
            </div>
          </div>
        </div>
      ))}
      <div className="counter">{`Items: ${cart.length}`}</div>
    </div>
  );
}

ReactDOM.render(<Women />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

  • Related