I have two React components.
The first one is just an export of an array that holds multiple objects.
VideoGameList.js
const VideoGameList = [
{
id: 1,
title: "Fire Emblem Engage",
src: vg01,
releaseDate: "01/20/2023",
price: 59.99,
quantity: 1,
inCart: true,
},
{
id: 2,
title: "Pokemon Violet",
src: vg02,
releaseDate: "11/18/2022",
price: 59.99,
quantity: 1,
inCart: false,
},
];
And the second one is a shopping cart
ShoppingCart.js
const ShoppingCart = (props) => {
return (
<>
<Header />
{VideoGameList.inCart === false && (
<div>
<h1 className="sc-empty-title">Your Shopping Cart Is Empty!</h1>;
<div className="shopping-cart-image">
<img src={shoppingCart} alt="empty-cart-image"></img>
</div>
</div>
)}
{VideoGameList.inCart ===
true(
<div className="videogame-content">
{VideoGameList.map(
(
{ id, title, src, releaseDate, price, quantity, inCart },
index
) => (
<div className="videogame">
<img key={src} src={src} alt={title} />
<div className="title-date">
<p className="title">{title}</p>
<p className="date">{releaseDate}</p>
</div>
<div>
<p className="price">${price}</p>
<button className="console">Add to Cart</button>
</div>
</div>
)
)}
</div>
)}
</>
);
};
export default ShoppingCart;
Under the VideoGameList
object you'll notice a value of inCart
set to either true or false. Using conditional render I'm trying to make it so if all inCart object values are set to false, the shopping cart will be (technically) empty and an image will be displayed. But if even a single inCart object value is set to true, that image will be displayed in its own div and the empty shopping cart image will not be displayed. However, my code appears to be wrong as when I go to the ShoppingCart page the only thing that is displayed is the Header and everything underneath is a white screen. Everything that I've tried doesn't appear to be working. Please advice.
CodePudding user response:
It will be clearer and a little more efficient to reverse your logic, and check if some()
of your objects are in the cart first. This has the advantage of stopping early if there is an element in the cart, instead of having to always check every element in the array. It is also much clearer to test a positive condition rather than a negated one — 'if any is true...' vs 'if every is not true ...'
To only map those elements that are in the cart you can add a filter before your map()
call (if you are doing other things with the objects in the cart it may be worth handling this filtering earlier in the component or storing in state at some level).
<>
<Header />
{VideoGameList.some(v => v.inCart)
? (
<div className='videogame-content'>
{VideoGameList.filter(v => v.inCart).map( // filter before mapping ({ id, title, src, releaseDate, price, quantity, inCart }, index) => (
<div className='videogame'>
<img key={src} src={src} alt={title} />
<div className='title-date'>
<p className='title'>{title}</p>
<p className='date'>{releaseDate}</p>
</div>
<div>
<p className='price'>${price}</p>
<button className='console'>Add to Cart</button>
</div>
</div>
),
)}
</div>
)
: (
<div>
<h1 className='sc-empty-title'>Your Shopping Cart Is Empty!</h1>;
<div className='shopping-cart-image'>
<img src={shoppingCart} alt='empty-cart-image'></img>
</div>
</div>
)}
</>;
CodePudding user response:
VideoGameList.inCart
is undefined that's why doesn't catch none of your conditions. VideoGameList
is an array of objects and you can't access it like that. For example this will work, but is not dynamic and doesn't help in your case VideoGameList[0].inCart
. I would suggest to use
VideoGameList.every((v) => v.inCart // this will return for every object in array his inCart value