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:
handleAddProduct
is 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
CodePudding user response:
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>
</>
);
};
CodePudding user response:
Your Card.jsx file props declaration is not seems to be correct. Change this like bellow.
const Card = (props) => {
const { handleAddProduct } = props
return (
<>
[...your code]
</>
)
}
Just catch only props and declare the function on the next line like this. You cannot catch props and another value inside props together. you can also declare another props items like the same
const { handleAddProduct, items } = props
You can directly use the state [items] and function [handleAddProduct] on your jsx inside Card.jsx
CodePudding user response:
Just Update this Card.jsx file: Now Working
you just take only one Concept: props or {items,handleAddProduct}
const Card = (props) => {
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={() => {
props.handleAddProduct(item);
}}
>
<ShoppingCartIcon />
</span>
</div>
</div>
</div>
</div>
);
})}
</div>
</>
);
};