【问题标题】:React How to change child state based on parent functionReact 如何根据父函数更改子状态
【发布时间】:2019-08-13 15:14:19
【问题描述】:

我正在构建 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。很明显为什么......因为它取决于状态值(位于 Product 组件中)。因此,每次从购物车中删除商品时,我都必须将此状态设置为 0。简单......但为了做到这一点,我必须通过回调函数将它传递给父组件。然后更改此数量并再次将其传递给 Product 组件。但是当我这样做时,购物车项目与产品具有相同的柜台,而不是独立于每个产品。我很困惑,卡住了,不知道该怎么办。希望大家帮忙

【问题讨论】:

  • 只需将函数的引用作为道具传递给孩子。 &lt;Child parentFunction={this.myFunction} /&gt;
  • 如果您的意思是将 itemRemove 函数从父组件(App,js)作为道具传递给 Product 组件,那么还有另一个问题。功能 itemRemove 在 Cart 组件 onClick 中作为主 App 组件的道具调用。那么,如果它在 App 中呈现但函数本身在 Product 中,我将如何从 Cart 组件调用 itemRemove 函数?抱歉,有点糊涂,我知道

标签: reactjs


【解决方案1】:

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

第二个但更好的是使用Redux

ReactJS modify parent state from child component 的可能重复项?

【讨论】:

  • 应该注意的是,如果要实现 Redux,您的第一个解决方案仍然适用。您仍然需要通过 props 向下传递动作创建者,以便可以分派适当的状态更改。
【解决方案2】:

所以我这样解决了我的问题: 起初我摆脱了 Product 组件中的所有状态,因为它们在我的情况下没有用。在 Product 组件中,我只从 props 调用 AddToCart 函数。

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

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

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;

【讨论】:

    猜你喜欢
    • 2021-01-12
    • 1970-01-01
    • 2021-12-09
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 2019-10-20
    相关资源
    最近更新 更多