[英]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.