购物车组件未以正确的数量更新

时间:2019-05-27 05:18:30

标签: reactjs

当我增加单张卡并单击“添加”按钮时,已成功将一张或多张卡添加到购物车,但是当我先增加两张或三张卡,然后单击“添加”按钮时,相应的卡项目数量计数与所增加的不匹配值。

完整代码在这里-https://github.com/sivadass/react-shopping-cart

我认为问题出在Counter.js中,不是在递增时设置了先前的状态,而是在以后添加到购物卡中

import React, { Component } from "react";
import PropTypes from "prop-types";

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { value: this.props.productQuantity };
    this.increment = this.increment.bind(this);
    this.decrement = this.decrement.bind(this);
  }

  increment(e) {
    this.setState(
      prevState => ({
        value: Number(prevState.value) + 1
      }),
      function() {
        this.props.updateQuantity(this.state.value);
      }
    );
    e.preventDefault();
  }

  decrement(e) {
    e.preventDefault();
    if (this.state.value <= 1) {
      return this.state.value;
    } else {
      this.setState(
        prevState => ({
          value: Number(prevState.value) - 1
        }),
        function() {
          this.props.updateQuantity(this.state.value);
        }
      );
    }
  }

  feed(e) {
    this.setState(
      {
        value: this.refs.feedQty.value
      },
      function() {
        this.props.updateQuantity(this.state.value);
      }
    );
  }

  resetQuantity() {
    this.setState({
      value: 1
    });
  }
  render() {
    return (
      <div className="stepper-input">
        <a href="#" className="decrement" onClick={this.decrement}>
          –
        </a>
        <input
          ref="feedQty"
          type="number"
          className="quantity"
          value={this.state.value}
          onChange={this.feed.bind(this)}
        />
        <a href="#" className="increment" onClick={this.increment}>
          +
        </a>
      </div>
    );
  }
}

Counter.propTypes = {
  value: PropTypes.number
};

export default Counter;

1 个答案:

答案 0 :(得分:2)

问题是您的所有组件都通过index.js消耗了存储在父级中的相同数量的值。您的购物车将从任何Counter中获取最近更新的计数值,并使用该值添加所选项目。您需要为每个Product隔离数量/数量。

我克隆了您的存储库,并通过对Product.js组件进行了更新来解决此问题。

我给了Product.js自己的私人数量来跟踪

class Product extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedProduct: {},
      quickViewProdcut: {},
      quantity: 1,
      isAdded: false
    };

    this.updateQuantity = this.updateQuantity.bind(this)
  }

创建一个事件处理程序,以更新其自身的状态量。

  updateQuantity(value){
    this.setState({
      quantity: value
    })
  }

更新quantityrender()的定义,以使用我们孤立的状态值而不是存储在父级中的值。

let quantity = this.state.quantity;

将上面的事件处理程序作为道具传递给Counter

 <Counter
  productQuantity={quantity}
  updateQuantity={this.updateQuantity}
  resetQuantity={this.resetQuantity}
/>

整合这些更改后,您的功能将完全正常运行。参见下面的完整代码:

import React, { Component } from "react";
import Counter from "./Counter";

class Product extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedProduct: {},
      quickViewProdcut: {},
      quantity: 1,
      isAdded: false
    };

    this.updateQuantity = this.updateQuantity.bind(this)
  }

  updateQuantity(value){
    this.setState({
      quantity: value
    })
  }

  addToCart(image, name, price, id, quantity) {
    this.setState(
      {
        selectedProduct: {
          image: image,
          name: name,
          price: price,
          id: id,
          quantity: quantity
        }
      },
      function() {
        this.props.addToCart(this.state.selectedProduct);
      }
    );
    this.setState(
      {
        isAdded: true
      },
      function() {
        setTimeout(() => {
          this.setState({
            isAdded: false,
            selectedProduct: {}
          });
        }, 3500);
      }
    );
  }
  quickView(image, name, price, id) {
    this.setState(
      {
        quickViewProdcut: {
          image: image,
          name: name,
          price: price,
          id: id
        }
      },
      function() {
        this.props.openModal(this.state.quickViewProdcut);
      }
    );
  }
  render() {
    let image = this.props.image;
    let name = this.props.name;
    let price = this.props.price;
    let id = this.props.id;
    let quantity = this.state.quantity;
    return (
      <div className="product">
        <div className="product-image">
          <img
            src={image}
            alt={this.props.name}
            onClick={this.quickView.bind(
              this,
              image,
              name,
              price,
              id,
              quantity
            )}
          />
        </div>
        <h4 className="product-name">{this.props.name}</h4>
        <p className="product-price">{this.props.price}</p>
        <Counter
          productQuantity={quantity}
          updateQuantity={this.updateQuantity}
          resetQuantity={this.resetQuantity}
        />
        <div className="product-action">
          <button
            className={!this.state.isAdded ? "" : "added"}
            type="button"
            onClick={this.addToCart.bind(
              this,
              image,
              name,
              price,
              id,
              quantity
            )}
          >
            {!this.state.isAdded ? "ADD TO CART" : "✔ ADDED"}
          </button>
        </div>
      </div>
    );
  }
}

export default Product;