Reputation: 1545
I have the following class Component that is handling some quantity changes an updating the price of a sku from stripes API.
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. 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
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 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
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>
)
}
Upvotes: 0
Views: 399
Reputation: 9364
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
. 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. 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:
return (
<>
<form>
...
</form>
<button onClick={() => this.props.handleCart(id, productId, this.state.quantity)}>
Add to Cart
</button>
</>
)
Upvotes: 1