to learn react im trying to implement a basic shop.
My Idea was to have many product-images. If an user clicks on an product-image this image turns around and shows something like comments, rating, etc of the product.
For this question i have 3 js Files: Container.js (contains everything from the product-cards to navbar etc), ProductList.js (returns the UL with all the different Products) and ItemCard.js (returns the actual product as LI ).
My Goal is to just invert the backsideVisible value.
I provide an minimal example for better understanding:
Container.js:
function Container() {
const [item, setItem] = useState([{
title: "some product title",
price: "14.99$",
backsideVisible: false
id: 1
}]);
function handleTurn(event, itemId) {
//here i want to change the backsideVisible value
event.preventDefault();
setItem(item.map(item => {
if(item.id === itemId) {
item.backsideVisible = !item.backsideVisible;
}
}))
}
return(
<ProductList items={item} handleTurn={handleTurn}/>
);
}
ProductList.js:
function ProductList(props) {
return(
<ul>
<CardItem items={props.items} handleTurn={props.handleTurn} />
</ul>
);
}
CardItem.js
function CardItem(props) {
return(
{props.items.map(item =>(
<li key={item.id} onClick={event => props.handleTurn(event, item.id)}>
product-image etc...
</li>
))}
);
}
But everytime i try this, ill get an "TypeError: can't access property "id", item is undefined" error. As soon as i change the handleTurn Method to something like
function handleTurn(event, itemId) {
event.preventDefault();
console.log(itemId);
}
everything works fine and the console displays the id of the clicked item. So for me it seems, that my handleTurn Function has some errors.
Do you guys have any idea where my fault is?
Your help is much appreciated. Thank you.
You're setting item (which should really be called items since it's an array. names matter) to an array of undefined elements, because your map() callback doesn't return anything:
setItem(item.map(item => {
if(item.id === itemId) {
item.backsideVisible = !item.backsideVisible;
}
}))
Either return the updated object:
setItem(item.map(item => {
if(item.id === itemId) {
item.backsideVisible = !item.backsideVisible;
}
return item;
}))
or have the whole expression be a returned object:
setItem(item.map(item => ({
...item,
backsideVisible: item.id === itemId ? !item.backsideVisible : item.backsideVisible
})));