简体   繁体   中英

How to update multiple state in react js

I am not sure weather the title of the question is right or not. I run into some problem and i have no idea how to solve them.

In my app there is cart page there is list of items. And each item has a field quantity.which can be updated. My problem Here is when i initiate i state quantity and make two function out of it which increase and decrease the quantity.but the problem is when i click on addQuantity it updates all the products quantity at the same time. I have really no idea to solve this i have been trying to figure out from last couple of days. These are the two items.

物品图片

These are my codes

class CartContainer extends React.Component { state = { quantity: 1, };

componentDidMount() { this.props.getItemsAddedToCart(); }

render() {

const addItem = () => {
  this.setState({
    quantity: this.state.quantity + 1,
  });
};

const removeItem = () => {
  this.setState({
    quantity: this.state.quantity - 1,
  });
};

Cart.js

return cartData.map((item, index) => { return (

      <Grid item xs={4} container justify="space-around">
        <CartItemDetails
          quantity={quantity}
          addItem={addItem}
          removeItem={removeItem}
          addQty={addQuantity}
          subQty={subtractQuantity}
          cart={item}
        />
      </Grid>
    </Grid>
  </Grid>
);

CartItemDetail.js

return (
  <Grid container className="cart-item-details">

    <Grid xs={12} md={4}>
      {!this.props.team ? (
        <Grid className="counter" xs={12} container>
          <Grid container justify="center" alignItems="center" xs={4}>
            <button
              onClick={this.props.removeItem}
              className="decrement"
            ></button>
          </Grid>
          <Grid container justify="center" alignItems="center" xs={4}>
            <span>{this.props.quantity}</span>
          </Grid>
          <Grid container justify="center" alignItems="center" xs={4}>

            <button
              onClick={this.props.addItem}
              className="increment"
            ></button>
          </Grid>
        </Grid>
      ) : (
        ""
      )}

Any help would be great I really want to figure this out.

Declare your state like the below

state={
quantity:{}
}

use product id or something unique to make the key of quantity

const addItem = (id) => {
  this.setState({
    quantity: {
     ...this.state.quantity,
     [id]:this.state.quantity[id]+1
     }
  });
};

const removeItem = (id) => {
  this.setState({
    quantity: {
     ...this.state.quantity,
     [id]:this.state.quantity[id]-1
     }
  });
};
      <Grid item xs={4} container justify="space-around">
        <CartItemDetails
          quantity={this.state.quantity[id]||0}
          addItem={addItem}
          removeItem={removeItem}
          addQty={addQuantity}
          subQty={subtractQuantity}
          cart={item}
        />
      </Grid>
    </Grid>
  </Grid>
);

You're only keeping one value for the quantity in your state, so all of your cart items rendered by Cart.js use the same value.

You'll need to track a quantity for each item in your cart, here's an example of the state set for each item:

this.state = {
      items: [
        {
          id: 1,
          name: "Jeans",
          quantity: 1
        },
        {
          id: 2,
          name: "Jacket",
          quantity: 2
        }
      ]
    };

and the functions to increase and decrease an item

increaseItemQuantity(id) {
    return () => {
      const itemIndex = this.state.items.findIndex(item => item.id === id);
      const nextItems = Array.from(this.state.items);
      console.log(itemIndex);
      nextItems[itemIndex].quantity = nextItems[itemIndex].quantity + 1;
      this.setState([...nextItems]);
    };
  }

  decreaseItemQuantity(id) {
    return () => {
      const itemIndex = this.state.items.findIndex(item => item.id === id);
      const nextItems = Array.from(this.state.items);
      console.log(itemIndex);
      nextItems[itemIndex].quantity = Math.max(
        1,
        nextItems[itemIndex].quantity - 1
      );
      this.setState([...nextItems]);
    };
  }

(this can be made much cleaner, but I'm leaving it as it is for the purposes of demonstration)

and then in the render:

render() {
    return (
      <div className="App">
        <div>
          {this.state.items.map((item, index) => (
            <div key={item.id}>
              {item.name} x{item.quantity}
              <br />
              <button
                type="button"
                onClick={this.decreaseItemQuantity(item.id)}
              >
                Decrease
              </button>
              <button
                type="button"
                onClick={this.increaseItemQuantity(item.id)}
              >
                Increase
              </button>
              <br />
              <br />
            </div>
          ))}
        </div>
      </div>
    );
  }

Try it here: https://codesandbox.io/s/solitary-dawn-8gpjl?file=/src/App.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM