I'm stuck in project because my functional component do not re-render when I update this state.
const OneProduct = (props) => {
return (
<div className='productincart'>
<div className='name'>{props.name}</div>
<div className='price'>Price: {props.price}</div>
<div className='quantity'>{props.quantity}</div>
</div>)
}
const InsideCart = (props) => {
const cartTemporary = props.sendCart
const [cart, setCart] = useState([])
useEffect(() => {
setCart(cartTemporary)
}, [cartTemporary])
const showCart = () => {
console.log(cart)
}
return (
<div className='insidecart'>
{cart.map(product => <OneProduct name={product.name} price=
{product.price} quantity={product.quantity} key={uniqid()} />)}
<button onClick={showCart}>SHOW CART</button>
</div>
)
}
In code above, I putting products from shop to the cart
, next I want to display it on the screen. When I'm putting new item to the cart
(new object in cart
array), everything works fine. When I'm only update quantity of object already exist in cart array, nothing happens. After quantity updating, cart
is updated with new value, but it doesn't causing re-render of component.
That is problem to solve, how to make component re-render after quantity value update.
Below format of objects which I add to cart
, also added mechanism of adding and increasing quantity.
const Products = (props) => {
const initialProducts = [
{ id: 0, name: "Fish - Betta splendens - Plakat Koi - Siamese fighting fish", image: image0, price: 23.17, quantity: 1 },
{ id: 1, name: "Fish - Betta splendens - Plakat - Siamese fighting fish", image: image1, price: 10.12, quantity: 1 },
{ id: 2, name: "Fish - Phenacogrammus interruptus - Congo tetra", image: image2, price: 5.19, quantity: 1 },
{ id: 3, name: "Fish - Thayeria boehlkei - Pinguin tetra", image: image3, price: 1.31, quantity: 1 },
{ id: 4, name: "Fish - Pterophyllum scalare - Angelfish", image: image4, price: 5.77, quantity: 1 },
{ id: 5, name: "Fish - Boeseman's rainbowfish Melanotaenia - Boesemani", image: image5, price: 4.90, quantity: 1 },
{ id: 6, name: "Fish - Ram cichlid - Mikrogeophagus ramirezi", image: image6, price: 4.61, quantity: 1 },
{ id: 7, name: "Fish - Corydoras aeneus sp.black venezuela", image: image7, price: 2.87, quantity: 1 },
]
const [products, setProducts] = useState(initialProducts)
const [toCart, setToCart] = useState([])
const getProductId = (e) => {
const idString = e.target.dataset.id
const id = Number(idString)
return id
}
const getProductById = (e) => {
const id = getProductId(e)
const itemFound = products.find(product => product.id === id)
const foundedOrNot = toCart.find(product => product === itemFound)
if (foundedOrNot === undefined) {
setToCart([...toCart, itemFound])
}
else {
const index = toCart.findIndex(product => product === itemFound)
toCart[index].quantity = toCart[index].quantity 1
}
}
return (
<div className="products">
<Nav sendToCart={toCart} />
<InsideCart sendCart={toCart} />
<div className='container'>{products.map((product) => <Product onClick={getProductById} title={product.name} img={product.image} price={product.price} id={product.id} key={product.id} />)}</div>
</div>
);
};
Also add simple component which determines rendering what is inside the cart.
const OneProduct = (props) => {
return (<div className='productincart'><div className='name'>{props.name}</div> <div className='price'>Price: {props.price}</div><div className='quantity'>{props.quantity}</div></div>)
}
CodePudding user response:
Your event capture mechanism is incorrectly implemented.
for solution you should replace it with the following:
<button onClick={() => showCart()}>SHOW CART</button>
You should check this link for the reason for the solution:
shortly, article includes this:
The problem with this syntax is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem.
CodePudding user response:
I already solved the problem. Issue was not using setToCart
in product
component. Thank you guys for all advices!
Updated code below:
const getProductById = (e) => {
const id = getProductId(e)
const itemFound = products.find(product => product.id === id)
const foundedOrNot = toCart.some(product => product === itemFound)
if (foundedOrNot === false) {
setToCart([...toCart, itemFound])
}
else {
const index = toCart.findIndex(product => product === itemFound)
const newCart = toCart.map(cart => {
if (cart.id === index) {
cart.quantity = cart.quantity 1
return cart
}
return cart
})
setToCart(newCart)
}
}