Reputation: 304
I have working code in App.jsx
. Everything is working when this written together in one file.
const App = props => {
const [cartProducts, setCartProducts] = useState([]);
const [products, setProducts] = useState(getProducts());
//const [searchValue, setSearchValue] = useState();
const handleAddProductToCart = productID => {
setCartProducts([...cartProducts, productID]);
};
const handleRemoveFromCart = productID => {
const newCartProducts = cartProducts.filter(id => id !== productID);
setCartProducts(newCartProducts);
};
/*const filterItems = ({ description, title }) => {
return title.toLocaleLowerCase().indexOf(searchValue.toLocaleLowerCase())
|| description.toLocaleLowerCase().indexOf(searchValue.toLocaleLowerCase())
}*/
return (
<>
<Header/>
<Search/>
<Sidebar/>
<div>
{products.map(product => {
const { id, title, description, image } = product;
let haveInCart = false;
cartProducts.forEach(productID => {
if (productID === id) {
haveInCart = true;
}
});
return (
<Card key={id} className="item-card">
<CardImg src={image} alt={title} className="item-img" style={{ height: '260px' }} />
<CardBody style={{ border: 'none' }} className="custom-card-body">
<CardTitle style={{ border: 'none' }} className="custom-card-title">{title}</CardTitle>
<CardText style={{ border: 'none' }} className="custom-card-text">{description}</CardText>
<FontAwesomeIcon icon={faCartPlus} className="add-icon" onClick={() => handleAddProductToCart(id)} />
</CardBody>
</Card>
);
})}
<h2>Your Cart</h2>
{cartProducts.length > 0
? cartProducts.map(productID => {
const productIndex = products.findIndex(product => {
return product.id === productID;
});
let { id, title, image } = products[productIndex];
return (
<Card key={id} className="item-card">
<CardImg src={image} alt={title} className="item-img" style={{ height: '260px' }} />
<CardBody style={{ border: 'none' }} className="custom-card-body">
<CardTitle style={{ border: 'none' }} className="custom-card-title">{title}</CardTitle>
<FontAwesomeIcon icon={faTrash} className="remove-icon" onClick={() => handleRemoveFromCart(id)} />
</CardBody>
</Card>
);
})
: "Yor Cart is Empty :("}
</div>
</>
)
}
export default App;
I want to put product Card and cart Card into it's own component. And when I'm doing it, like this
const Product = ({product}) => {
const { id, title, description, image } = product;
return (
<Card key={id} className="item-card">
<CardImg src={image} alt={title} className="item-img" style={{ height: '260px' }} />
<CardBody style={{ border: 'none' }} className="custom-card-body">
<CardTitle style={{ border: 'none' }} className="custom-card-title">{title}</CardTitle>
<CardText style={{ border: 'none' }} className="custom-card-text">{description}</CardText>
<FontAwesomeIcon icon={faCartPlus} className="add-icon" /*onClick={() => handleAddProductToCart(id)}*/ />
</CardBody>
</Card>
)
}
I'm not getting properties of product in my Card. I want to make my code better organized and save it's functionality. How to access those states from Product
and Cart
component?
EDIT Here's the link to codesandbox https://codesandbox.io/s/late-cookies-r2inh?file=/src/App.jsx&fbclid=IwAR38tcE39tVL51YpG4_6A1HRz-kth1GSIocQWMPrU3QXepc5CHUNn-ZqiG8
EDIT 2 How I can make items in cart be displaying beside Product
component, on the left side? Should I create entire Cart component for it?
Upvotes: 0
Views: 35
Reputation: 372
Your Product.jsx file should look like this:
import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCartPlus } from "@fortawesome/free-solid-svg-icons";
import Card from "react-bootstrap/Card";
import CardBody from "react-bootstrap/Card";
import CardImg from "react-bootstrap/CardImg";
import CardTitle from "react-bootstrap/Card";
import CardText from "react-bootstrap/Card";
const Product = ({ product, handleAddProductToCart }) => {
const { id, title, description, image } = product;
return (
<Card key={id} className="item-card">
<CardImg
src={image}
alt={title}
className="item-img"
style={{ height: "260px" }}
/>
<CardBody style={{ border: "none" }} className="custom-card-body">
<CardTitle style={{ border: "none" }} className="custom-card-title">
{title}
</CardTitle>
<CardText style={{ border: "none" }} className="custom-card-text">
{description}
</CardText>
<FontAwesomeIcon
icon={faCartPlus}
className="add-icon"
onClick={() => handleAddProductToCart(id)}
/>
</CardBody>
</Card>
);
};
export default Product;
And in your App.jsx you can map the products array like this:
{products.map((product) => (
<Product
product={product}
key={product.id}
handleAddProductToCart={handleAddProductToCart}
/>
))}
EDIT: https://codesandbox.io/s/determined-swartz-5q2fo I edited the codesandbox, i made the Product component accept both add and remove product callback and the "haveInCart" prop. It will decide which icon and which callback to use base on that prop. I'm not sure about this approch tho
Upvotes: 2