简体   繁体   English

如何在 ReactJS 中将数量从一个组件传递到另一个组件,其中它们是独立的但位于同一个父级中

[英]How to pass quantity from component to component in ReactJS where they are independent but live in the same parent

I have the following class Component that is handling some quantity changes an updating the price of a sku from stripes API.我有以下 class 组件,它处理一些数量变化,并从条纹 API 更新 sku 的价格。

The crux of the issue is that I need the quantity for the sku inside the Cart component, but the quantity state is handled inside the Product component, and it needs to be separate because you can change the sku in the dropdown menu and the product will change state, so if the cart component is in the product then the state clears and is not persistent.问题的症结在于我需要 Cart 组件中 sku 的数量,但是 state 的数量是在 Product 组件中处理的,它需要分开,因为您可以在下拉菜单中更改 sku,产品将更改 state,因此如果购物车组件在产品中,则 state 会清除并且不会持久化。 Also I will need a way for the cart to add to the state instead of just replacing it on setSkuObject not sure if that's possible either此外,我需要一种将购物车添加到 state 的方法,而不是仅仅在setSkuObject上替换它,不确定这是否可能

Any help would be greatly appreciated任何帮助将不胜感激

Product component产品组成


  class Product extends React.Component {
    constructor(props) {
      super(props)
  
      this.state = {
        stripe: null,
        quantity: 1,
        price: props.price,
        skuObject: null,
      }
  
      this.handleInputChange = this.handleInputChange.bind(this)
    }
    
  
    handleInputChange(event) {
      const target = event.target
      const { quantity } = this.state
      const { price } = this.props
  
  
      this.setState({
        quantity: parseInt(target.value),
      })
      this.setState({
        price: price * parseInt(target.value),
      })
    }
  
    render() {
      const { id, currency, name, productId } = this.props
      const { quantity, price, skuObject } = this.state
  
      //console.log(quantity);
  
      const priceFloat = (price / 100).toFixed(2)
      const formattedPrice = Intl.NumberFormat("en-US", {
        style: "currency",
        currency,
      }).format(priceFloat)
  
      return (
        <>
          <form className="name-buy">
            <label>
              Quantity
              <input
                type="number"
                name="amount"
                min="1"
                value={this.state.quantity}
                onChange={this.handleInputChange}
              />
            </label>
          </form>
          <form
            className="submit"
            onSubmit={this.handleSubmit(id, productId, quantity)}
          >
            <div>
              <h2>
                {name} ({formattedPrice})
              </h2>
              <button type="submit">Buy Now</button>
            </div>
          </form>
        </>
      )
    }
  }

cart class component购物车 class 组件

class Cart extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      sku: null,
      quantity: null,
    }
  }
  render() {
    const { skuObject } = this.props
    return <CartBox>Cart {skuObject} {/*would like to have quantity here*/} </CartBox>
  }
}

It lives inside A StoreDetails functional component它存在于一个 StoreDetails 功能组件中

const StoreDetails = ({ data, location }) => {
    const setSkuOnce = data.allDatoCmsStore.edges.map(
      ({ node: product }, index) => {
        if (product.defaultProduct === true) {
          //console.log(product.skuId);
          return product.skuId
        }
      }
    )
  
    //console.log(setSkuOnce)
  
    var filtered = setSkuOnce.filter(function(el) {
      return el != null
    })
  
    const [value, setValue] = useState({
      skuId: filtered[0],
    })
  
    const run = event => {
      //console.log(event);
      setValue({ skuId: event })
    }
  
    const [skuObject, setSkuObject] = useState()
    const handleCart = (sku, productId, quantity) => {
      return event => {
        event.preventDefault()
        setSkuObject(sku)
      }
    }
  
    return (
      <Layout>
        <StoreHero>
          <Link to="/store">
            <BsArrowLeft />
            Back
          </Link>
          <Alert test="test" hello="hello" hash={location.hash} />
  
          {/* <ShowItem props={data}/> */}
  
          <Cart skuObject={skuObject} />
  
          {data.allDatoCmsStore.edges.map(({ node: sku }) => (
            <React.Fragment key={sku.skuId}>
              {value.skuId === sku.skuId ? (
                <ProductGrid>
                  <Img fluid={sku.image.fluid} />
                  <ProductCol>
                    <h1>{sku.productTitle}</h1>
                    <FirstThreeWrap>
                      <form className="variant">
                        <label>
                          <span>Product Variant</span>
                          <select
                            value={value.skuId}
                            onChange={event => run(event.target.value)}
                          >
                            {data.allDatoCmsStore.edges.map(({ node: sku }) => (
                              <React.Fragment key={sku.skuId}>
                                <option value={sku.skuId}>{sku.title}</option>
                              </React.Fragment>
                            ))}
                          </select>
                        </label>
                      </form>
  
                      {/* <ShowItem setValue={setValue}/> */}
                      <Product
                        key={sku.id}
                        id={sku.skuId}
                        productId={sku.productId}
                        currency="cad"
                        price={sku.price}
                        name={sku.title}
                      />
                      <button onClick={handleCart(sku.skuId, sku.productId)}> {/* I NEED TO PASS THE QUANTITY IN HERE */}
                        Add to Cart
                      </button>
                    </FirstThreeWrap>
                    <div
                      className="description"
                      dangerouslySetInnerHTML={{ __html: sku.productDescription }}
                    />
                    <QuestionForm skuId={sku.skuId} name={sku.title} />
                  </ProductCol>
                </ProductGrid>
              ) : null}
            </React.Fragment>
          ))}
        </StoreHero>

      </Layout>
    )
  }

If I've parsed all this correctly, then it would seem you could achieve it by simply moving the "Add To Cart" button inside Product .如果我已经正确解析了所有这些,那么您似乎可以通过简单地移动Product中的“添加到购物车”按钮来实现它。 I can't see any reason not to as they are rendered one after the other and use exactly the same data from the map function.我看不出有任何理由不这样做,因为它们一个接一个地渲染,并使用来自 map function 的完全相同的数据。 You would just pass the handler down like so:您只需像这样传递处理程序:

<Product
  key={sku.id}
  id={sku.skuId}
  productId={sku.productId}
  currency="cad"
  price={sku.price}
  name={sku.title}
  handleCart={handleCart}
/>

And then in Product render it like this:然后在Product中渲染如下:

return (
  <>
    <form>
      ...
    </form>
    <button onClick={() => this.props.handleCart(id, productId, this.state.quantity)}>
      Add to Cart
    </button>
  </>
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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