once again, you never want to directly update the state array, instead you should iterate through each item in the array using the .map() method, allowing you to select the element you wish to change, because this method creates a new array rather than changing the original.
So for example, to manage state of a checkbox for an item you would do the following:
function handleToggleItem(id) {
// map over the items, and if the id matches, toggle the packed property
setItems((items) =>
items.map((item) =>
item.id === id ? { ...item, packed: !item.packed } : item
)
);
}
So in our function we’re mapping over each element (item) in the items array, and if the id passed in matches the item.id, then spread out the existing item and toggle the “packed” object value to be the opposite of whatever it was when it was passed in, essentially flipping the state value for that element.
In terms of how this is eventually called, you would do the following:
function Item({ itemProp, onDeleteItem, onToggleItem }) {
return (
<li>
<input type="checkbox" onChange={() => onToggleItem(itemProp.id)} />
<span style={itemProp.packed ? { textDecoration: "line-through" } : {}}>
{itemProp.quantity} {itemProp.description}
</span>
<button onClick={() => onDeleteItem(itemProp.id)}>❌</button>
</li>
);
}
so whenever the checkbox changes (onChange) then call the onToggleItem which was passed in as props, and pass the id to it. Now because itemProp is also passed in (the entire item object) it will then derive the value of itemProp.packed to determine if it’s true or false, and apply the styling accordingly.