React如何根据父函数更改子状态

时间:2019-03-22 15:25:08

标签: reactjs

我正在出于学习目的构建React项目(杂志)。我被困在购物车的柜台上。每个产品都有数量。每次单击添加到购物车按钮时,它增加1。当我单击关闭按钮时,项目消失了,但是它的数量被保存了,尽管我希望将其设置为0。所以下一次我点击添加到购物车,数量再次从0开始。 听起来很简单,但我被困住了。似乎我已经尝试了几乎所有我都不知道如何解决此问题的方法。

这是主要组成部分:

`class App extends React.Component {
      constructor() {
        super();
        this.handleAddToCart = this.handleAddToCart.bind(this);
        this.itemRemove = this.itemRemove.bind(this);
        this.state = {
          products: {products: []},
          cart: [],
          quantity: 0,
          itemQ: 0,
        };
      }

    handleAddToCart(selectedProducts) {
    let cartItems = this.state.cart;
    let productID = selectedProducts.id;
    let productQty = selectedProducts.quantity;

    if(this.checkProduct(productID)) {
      let index = cartItems.findIndex(x => x.id == productID);
      cartItems[index].quantity = productQty;
      this.setState({
        cart: cartItems,
      });
    } else {
      cartItems.push(selectedProducts);
    }
    this.setState({
      cart: cartItems,
    });
  };



itemRemove(id, amount, e) {
    let cart = this.state.cart;
    let test = amount;
    let index = cart.findIndex(x => x.id == id);
    let productQty = amount;
    cart[index].quantity = Number(productQty);
    cart.splice(index, 1);
    this.setState({
      cart: cart,
      itemQuantity: 0,
      itemQty: 0
    });
    e.preventDefault();
  };

checkProduct(productID) {
    let cart = this.state.cart;
    return cart.some(function(item) {
      return item.id === productID;
    });
  }

render() {
    return(
      <div className="main">
        <Products
          addToCart={this.handleAddToCart} 
          productsList={this.state.products}
          itemQuantity={this.state.itemQuantity}
        />
        <Cart 
          cartItems={this.state.cart}
          itemRemove={this.itemRemove}
          quantity={this.state.itemQuantity}
        />
      </div>
    );
  }
}

购物车组件(我在其中添加和删除购物车中的商品)

render() {
        let cartItems;
        cartItems = this.state.cart.map(product => {
            return(

            <CSSTransition key={product.id} classNames={'fade'} timeout={{enter:500, exit: 300}}>       
                <div className="product-item-wrapper">
                    <div className="product-item">
                        <div 
                            className="item-remove"
                            onClick={this.props.itemRemove.bind(this, product.id, product.quantity)}
                        >
                        </div>
                        <div className="item-img">
                            {product.thumb}
                        </div>
                        <div className="item-info">
                            <p className="item-name">{product.title}</p>
                            <p className="item-desc">{product.style}</p>
                            <p className="item-quantity">Quantity: {product.quantity}</p>
                        </div>
                        <div className="price">
                            <p>$ {product.price}</p>
                        </div>

产品组件(我可以通过单击“添加到购物车”按钮将商品添加到购物车:

class Product extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedProduct: {},
            isAdded: false,
            itemQuantity: 0
        };
    }

addToCart(style, title, price, id, thumb, quantity) {
        this.setState(
            {
                selectedProduct: {
                    style: style,
                    title: title,
                    price: price,
                    id: id,
                    thumb: thumb,
                    quantity: quantity
                },
            },
            function() {
                this.props.addToCart(this.state.selectedProduct);
            }
        );
        this.setState(
            {
            isAdded: true,
            itemQuantity: this.state.itemQuantity + 1,
            },
        );
    }

render() {

        const {id, title, style, price, currency, installments} = this.props;
        const quantity = this.state.itemQuantity;


        return(
            <div className="product">

                <div 
                    className="buy-btn"
                    onClick={this.addToCart.bind(
                        this,
                        style,
                        title,
                        price,
                        id,
                        thumb,
                        quantity
                    )}
                >
                    Add to cart
                </div>
            </div>
        );
    }

我尝试了很多事情。当我删除项目,然后再次将其添加到购物车时,其数量未设置为0。显而易见的原因...因为它取决于状态值(在产品组件中)。因此,每次我从购物车中删除商品时,我都必须将此状态设置为0。很简单...但是为了做到这一点,我必须通过回调函数将其传递给父组件。然后更改此数量,然后再次将其传递给产品组件。但是,当我这样做时,购物车中的商品与商品具有相同的计数器,而不是彼此独立。我很困惑,被困住了,不知道该怎么办。希望您会帮助Area where I stuck

2 个答案:

答案 0 :(得分:0)

为此,最快的两个解决方案是在父组件中创建一个函数,以更改相关状态。然后,您将能够通过构造函数将函数注入子组件。然后只要您需要更改父状态就可以调用注入函数!

第二个更好的方法是使用Redux

可能是ReactJS modify parent state from child component的副本吗?

答案 1 :(得分:0)

所以我这样解决了我的问题: 最初,我摆脱了Product组件中的所有状态,因为在我的案例中它们没有用。在产品组件中,我仅从道具中调用AddToCart函数。

this.props.addToCart({ 
style: style, 
title: title, 
price: price, 
id: id, 
thumb: thumb 
});

我从该函数中删除了 quantity 变量作为参数,因为父组件(App)中的状态就足够了。在应用程序中,我更改 handleAddToCart itemRemove 功能:

handleAddToCart(selectedProduct) { 
let cartItems = this.state.cart; 
let productID = selectedProduct.id; 
if(this.checkProduct(productID)) { 
let index = cartItems.findIndex(x => x.id == productID); 
cartItems[index].quantity += 1; 
this.setState({ 
cart: cartItems, 
}); 
} else { 
selectedProduct.quantity = 0; 
cartItems.push(selectedProduct); 
} 
this.setState({ 
cart: cartItems, 
}); 
};

在itemRemove中,我只更改了一行,然后:cart[index].quantity = 0;