I’m finishing a page with shopping cart. I have a function that adds products to the cart and that works in other sections of the page perfectly. The problem is that on the home page the function tells me:
handleAddProductis not a function atonClick.
Here I leave the components that are causing problems
App.js
const [cartItems, setCartItems] = useState([]);
const handleAddProduct = (product) => {
toast('✔️ Producto añadido')
console.log('Producto seleccionado')
const ProductExist = cartItems.find((item) => item.id === product.id);
if(ProductExist){
setCartItems(
cartItems.map((item)=>
item.id === product.id
? {...ProductExist, quantity: ProductExist.quantity + 1}
: item
)
);
} else {
setCartItems([...cartItems, {...product, quantity: 1}]);
}
};
...
// Here I am passing the handleAddProduct function as a prop to the 'Inicio.jsx' component
<Route path='/' exact element={<Inicio handleAddProduct={handleAddProduct} />}/>
Inicio.jsx
Here I am importing the handleAddProduct function as a prop to the ‘Inicio.jsx’ component and then passing it back as a prop to the Cards.jsx component
const Inicio = ({ handleAddProduct }) => {
return (
<>
<section className="new__product__section">
<h2 className="title__section__card">Nuevos Productos</h2>
<Card items={CardItemsHero} handleAddProduct={handleAddProduct} />
<div className="btn__link__container">
<Button color="primary" variant="contained" size="large">
<Link to={'/catalogo'}>
Ver Catálogo
</Link>
</Button>
</div>
</section>
...
Card.jsx
HERE IS THE PROBLEM 1
const Card = (props, { handleAddProduct }) => {
return (
<>
<div className='card__section'>
{props.items.map(item => {
return(
<div className="product__card" key={item.id}>
<div className="product__tumb">
<img src={require('../../assets/' + item.image + '.png')} alt={item.title} />
</div>
<div className="product__details">
<span className="product__category">{item.type}</span>
<h3>{item.title}</h3>
<div className="product__bottom__details">
<div className="product__price">{'$ ' + item.price + '.00'}</div>
<div className="product__links">
<Link to={'/' + item.id}><InfoIcon /></Link>
<span onClick={()=>handleAddProduct(item)}>
<ShoppingCartIcon/>
</span>
</div>
</div>
</div>
</div>
)
})}
</div>
</>
)
}
CLARIFICATIONS: the page works perfectly. I am passing the same function in the same way to other components within another component, even with the same <span> line, and the products are added without any problem. I think it’s an error when importing the props in Card.jsx but I can’t think of what it could be because if I just put {props, handleAddProducts} the page stops working
Here is the repo: https://github.com/LuksFay/Fabianesi-page
>Solution :
The issue is with the Card component. React components receive only a single argument, the props object. In the code the Card component is attempting to destructure handleAddProduct from an undefined argument.
const Card = (props, {handleAddProduct}) => {
Destructure handleAddProduct from the first argument, the props object.
Example:
const Card = ({ handleAddProduct, items }) => { // <-- destructure all from props
return (
<>
<div className="card__section">
{items.map((item) => {
return (
<div className="product__card" key={item.id}>
<div className="product__tumb">
<img
src={require("../../assets/" + item.image + ".png")}
alt={item.title}
/>
</div>
<div className="product__details">
<span className="product__category">{item.type}</span>
<h3>{item.title}</h3>
<div className="product__bottom__details">
<div className="product__price">
{"$ " + item.price + ".00"}
</div>
<div className="product__links">
<Link to={"/" + item.id}>
<InfoIcon />
</Link>
<span
onClick={() => {
handleAddProduct(item);
}}
>
<ShoppingCartIcon />
</span>
</div>
</div>
</div>
</div>
);
})}
</div>
</>
);
};