Reputation: 13
I am changing the text colour in a list when the item is clicked. Ideally, I would like to have a toggle function so only 1 item is highlighted at a time. The following code works however I can't stop thinking there is a much better way.
import React, { useState } from "react";
const listItems = [
{
id: 1,
title: "About",
selected: true,
},
{
id: 2,
title: "Contact",
selected: false,
},
{
id: 3,
title: "Products",
selected: false,
},
];
const ListView = () => {
const [menuItems, setMenuItems] = useState(listItems);
const handleListClick = (id) => {
setMenuItems([...menuItems.map((item)=> {
if (item.id === id){
item.selected=!item.selected
}
return item
})])
};
return (
<>
<ul>
{listItems.map((item, index) => {
return (
<li
key={item.id}
onClick={() => handleListClick(item.id)}
style={item.selected ? { color: "red" } : { color: "Blue" }}
>
{item.title}
</li>
);
})}
</ul>
</>
);
};
export default ListView;
Any ideas on simplifying this...
Upvotes: 1
Views: 485
Reputation: 525
You can use the array index to update the item only without traversing the array like this
import React, { useState } from "react";
const listItems = [
{
id: 1,
title: "About",
selected: true,
},
{
id: 2,
title: "Contact",
selected: false,
},
{
id: 3,
title: "Products",
selected: false,
},
];
const ListView = () => {
const [menuItems, setMenuItems] = useState(listItems);
const handleListClick = (index) => {
const items = [...menuItems];
items[index].selected = !items[index].selected;
setMenuItems(items);
};
return (
<>
<ul>
{listItems.map((item, index) => {
return (
<li
key={item.id}
onClick={() => handleListClick(index)}
style={item.selected ? { color: "red" } : { color: "Blue" }}
>
{item.title}
</li>
);
})}
</ul>
</>
);
};
export default ListView;
Upvotes: 1