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

3
当我增加一个商品数量并点击添加按钮时,该商品将成功添加到购物车中。但是,当我先增加两个或三个商品的数量,然后再单击添加按钮时,相应的商品数量计数与增加的值不匹配。
完整代码在这里 -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;

https://sivadass.github.io/react-shopping-cart/ - dasitha
你需要在index.js中更改顶层的数量,并将其作为props传递给每个“Product”。你需要将它删除,并独立处理每个“Product”的“quantity”。 - Asaf Aviv
计数器应该在水果级别处理。如果您对一个项目进行递增,然后添加一个未递增的不同项目,则会获得该项目的递增数量。 - Chris Ngo
@dasitha,我在克隆你的repo后给你提供了一个答案。我添加的更改使你的功能按预期工作。如果这对你有用,请告诉我。 :) - Chris Ngo
@ChristopherNgo 谢谢。我会检查并告诉你。 - dasitha
@ChristopherNgo 非常感谢,兄弟...现在它已经很好地工作了... - dasitha
1个回答

2
问题在于您的组件都使用通过index.js存储在父级中的相同数量值。您的购物车从任何Counter中获取最后更新的计数值,并使用它来添加所选项目。您需要为每个Product隔离数量/计数。
我克隆了您的repo,通过对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
    })
  }

render()中的quantity定义更新为使用我们隔离的状态值,而不是存储在父级中的值。

新的回答
let quantity = this.state.quantity;

将事件处理程序作为prop传递给计数器
 <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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接